blob: b24dc0cab40a539cb9ca7df9faf1b689127a1839 [file] [log] [blame]
AleX Pelosi78a4bea2020-09-01 19:02:24 -07001/* SPDX-License-Identifier: GPL-2.0 */
Ken Tsou8acade12020-07-09 03:17:35 +08002/*
AleX Pelosi78a4bea2020-09-01 19:02:24 -07003 * Copyright 2020 Google, LLC
Ken Tsou8acade12020-07-09 03:17:35 +08004 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 */
15
16#define pr_fmt(fmt) KBUILD_MODNAME ": %s " fmt, __func__
17
18#include <linux/ctype.h>
19#include <linux/i2c.h>
20#include <linux/of.h>
21#include <linux/of_gpio.h>
AleX Pelosi90528cd2021-04-22 23:58:50 -070022#include <linux/of_irq.h>
Ken Tsou8acade12020-07-09 03:17:35 +080023#include <linux/gpio.h>
24#include <linux/gpio/driver.h>
25#include <linux/module.h>
26#include <linux/regmap.h>
27#include <linux/interrupt.h>
28#include <linux/debugfs.h>
29#include <linux/seq_file.h>
AleX Pelosi90528cd2021-04-22 23:58:50 -070030#include <linux/irqdomain.h>
31#include <linux/irq.h>
32#include <linux/irqchip.h>
AleX Pelosi32892282020-09-11 02:29:20 -070033#include "max_m5.h"
Ken Tsou8acade12020-07-09 03:17:35 +080034#include "max77759.h"
35#include "max77759_maxq.h"
Wasb Liuf19aa972020-11-13 23:36:08 +080036#include "gbms_storage.h"
Jenny Ho2c407222022-04-27 09:29:04 +080037#include "google_bms.h"
Ken Tsou8acade12020-07-09 03:17:35 +080038
AleX Pelosi90528cd2021-04-22 23:58:50 -070039
Ken Tsou8acade12020-07-09 03:17:35 +080040enum max77729_pmic_register {
41 MAX77729_PMIC_ID = 0x00,
42 MAX77729_PMIC_REVISION = 0x01,
43 MAX77729_PMIC_MAINCTRL = 0x02,
44 MAX77729_PMIC_INTSRC = 0x22,
45 MAX77729_PMIC_INTSRCMASK = 0x23,
46 MAX77729_PMIC_TOPSYS_INT = 0x24,
47 MAX77729_PMIC_TOPSYS_INT_MASK = 0x26,
48};
49
50#define MUSBC 0x08
51#define MFUEL 0x04
52#define MTOPS 0x02
53#define MCHGR 0x01
54
55#define MAX77759_GPIO_DIR_IN 0
56#define MAX77759_GPIO_DIR_OUT 1
57
58#define MAX77759_GPIO5_DIR_MASK (1 << 2)
59#define MAX77759_GPIO5_DIR(x) ((x) << 2)
60#define MAX77759_GPIO5_VAL_MASK (1 << 3)
61#define MAX77759_GPIO5_VAL(x) ((x) << 3)
Kyle Tso3651f9f2021-09-11 15:37:05 +080062#define MAX77759_GPIO6_DIR_MASK (1 << 5)
63#define MAX77759_GPIO6_DIR(x) ((x) << 5)
64#define MAX77759_GPIO6_VAL_MASK (1 << 6)
65#define MAX77759_GPIO6_VAL(x) ((x) << 6)
Ken Tsou8acade12020-07-09 03:17:35 +080066
67#define MAX77759_GPIO5_OFF 4
68#define MAX77759_GPIO6_OFF 5
69#define MAX77759_MIN_GPIO_OFF 4
70#define MAX77759_MAX_GPIO_OFF 5
71#define MAX77759_NUM_GPIOS 6
72
73#define MAX77759_GPIO_CONTROL_READ 0x23
74#define MAX77759_GPIO_CONTROL_WRITE 0x24
75
76#define MDEFAULT (0xF0 | ~(MUSBC | MFUEL | MCHGR))
77
78
79#define MAX77729_PMIC_INTSRCMASK_DEFAULT MDEFAULT
80#define MAX77729_PMIC_TOPSYS_INT_MASK_DEFAULT 0xff
81
82#define MAX77759_PMIC_INTSRCMASK_DEFAULT \
83 ~(MAX77759_PMIC_INTSRCMASK_MAXQ_INT_M | \
84 MAX77759_PMIC_INTSRCMASK_CHGR_INT_M)
85
86/* b/156527175: *_PMIC_TOPSYS_INT_MASK_SPR_7 is reserved */
87#define MAX77759_PMIC_TOPSYS_INT_MASK_MASK \
88 (MAX77759_PMIC_TOPSYS_INT_MASK_TSHDN_INT_M | \
89 MAX77759_PMIC_TOPSYS_INT_MASK_SYSOVLO_INT_M | \
90 MAX77759_PMIC_TOPSYS_INT_MASK_SYSUVLO_INT_M)
91
92#define MAX77759_PMIC_TOPSYS_INT_MASK_DEFAULT \
93 (MAX77759_PMIC_TOPSYS_INT_MASK_TSHDN_INT_M)
94
Wasb Liuf19aa972020-11-13 23:36:08 +080095#define MAX77759_STORAGE_SIZE 16
96#define MAX77759_STORAGE_BASE (MAX77759_PMIC_AP_DATAOUT0 + MAX77759_STORAGE_SIZE)
97
Ken Tsou8acade12020-07-09 03:17:35 +080098struct max77729_pmic_data {
99 struct device *dev;
100 struct regmap *regmap;
101 uint8_t pmic_id;
Wasb Liuf19aa972020-11-13 23:36:08 +0800102 uint8_t rev_id;
Ken Tsou8acade12020-07-09 03:17:35 +0800103
AleX Pelosi6852a072020-09-08 19:05:56 -0700104#if IS_ENABLED(CONFIG_GPIOLIB)
AleX Pelosi90528cd2021-04-22 23:58:50 -0700105 struct mutex irq_lock;
Ken Tsou8acade12020-07-09 03:17:35 +0800106 struct gpio_chip gpio;
AleX Pelosi90528cd2021-04-22 23:58:50 -0700107
108 /* threaded irq */
109 int irq_trig_falling[2];
110 u8 irq_trig_u;
111 u8 irq_mask;
112 u8 irq_mask_u;
Ken Tsou8acade12020-07-09 03:17:35 +0800113#endif
114 struct max77759_maxq *maxq;
115
116 struct i2c_client *fg_i2c_client;
Badhri Jagan Sridharan991b7b52020-11-10 00:00:35 -0800117 struct i2c_client *pmic_i2c_client;
118 void *ovp_client_data;
Ken Tsou8acade12020-07-09 03:17:35 +0800119 struct mutex io_lock;
120 int batt_id;
121
122 atomic_t sysuvlo_cnt;
123 atomic_t sysovlo_cnt;
124 struct dentry *de;
Wasb Liuf19aa972020-11-13 23:36:08 +0800125
126 struct delayed_work storage_init_work;
Wasb Liu7830d712021-01-20 15:30:44 +0800127
128 /* debug interface, register to read or write */
129 u32 debug_reg_address;
AleX Pelosi90528cd2021-04-22 23:58:50 -0700130
Ken Tsou8acade12020-07-09 03:17:35 +0800131};
132
AleX Pelosi78a4bea2020-09-01 19:02:24 -0700133static bool max77729_pmic_is_reg(struct device *dev, unsigned int reg)
Ken Tsou8acade12020-07-09 03:17:35 +0800134{
135 int ret;
136
137 switch (reg) {
138 case MAX77729_PMIC_ID:
139 case MAX77729_PMIC_REVISION:
140 case MAX77729_PMIC_MAINCTRL:
141 case MAX77729_PMIC_INTSRC:
142 case MAX77729_PMIC_INTSRCMASK:
143 case MAX77729_PMIC_TOPSYS_INT:
144 case MAX77729_PMIC_TOPSYS_INT_MASK:
145 ret = true;
146 break;
147 case MAX77759_PMIC_I2C_CNFG:
148 case MAX77759_PMIC_SWRESET:
149 case MAX77759_PMIC_CONTROL_FG:
150 ret = true;
151 break;
152 case MAX77759_PMIC_DEVICE_ID:
153 case MAX77759_PMIC_DEVICE_REV:
AleX Pelosifbc43122020-11-18 23:44:03 -0800154 case MAX77759_PMIC_FW_REV:
155 case MAX77759_PMIC_FW_SUB_REV:
Ken Tsou8acade12020-07-09 03:17:35 +0800156 case MAX77759_PMIC_UIC_INT1...MAX77759_PMIC_UIC_INT4_M:
157 case MAX77759_PMIC_AP_DATAOUT0...MAX77759_PMIC_AP_DATAIN32:
158 case MAX77759_PMIC_UIC_SWRST:
159 ret = true;
160 break;
161 default:
162 ret = false;
163 break;
164 }
165
166 return ret;
167}
168
169static struct regmap_config max777x9_pmic_regmap_cfg = {
170 .name = "max777x9_pmic",
171 .reg_bits = 8,
172 .val_bits = 8,
173 .val_format_endian = REGMAP_ENDIAN_NATIVE,
174 .max_register = MAX77729_PMIC_INTSRCMASK,
175 .readable_reg = max77729_pmic_is_reg,
176 .volatile_reg = max77729_pmic_is_reg,
177};
178
179static inline int max77729_pmic_readn(struct max77729_pmic_data *data,
180 int addr, u8 *val, int len)
181{
182 int rc;
183
184 rc = regmap_bulk_read(data->regmap, addr, val, len);
185 if (rc < 0)
186 pr_err("regmap_read failed for address %04x rc=%d\n",
187 addr, rc);
188
189 return rc;
190}
191
192static inline int max77729_pmic_writen(struct max77729_pmic_data *data,
193 int addr, const u8 *val, int len)
194{
195 int rc;
196
197 rc = regmap_bulk_write(data->regmap, addr, val, len);
198 if (rc < 0)
199 pr_err("regmap_write failed for address %04x rc=%d\n",
200 addr, rc);
201
202 return 0;
203}
204
205
206#define max77729_pmic_rd8(data, addr, val) \
207 max77729_pmic_readn(data, addr, val, 1)
208#define max77729_pmic_wr8(data, addr, val) \
209 max77729_pmic_writen(data, addr, (const u8[]){ val }, 1)
210
211/* no need for caching */
212static inline int max77729_pmic_rmw8(struct max77729_pmic_data *data,
213 int reg, u8 mask, u8 value)
214{
215 return regmap_write_bits(data->regmap, reg, mask, value);
216}
217
218int max777x9_pmic_reg_read(struct i2c_client *client,
219 u8 addr, u8 *val, int len)
220{
AleX Pelosid6150182021-03-05 18:10:44 -0800221 struct max77729_pmic_data *data;
Ken Tsou8acade12020-07-09 03:17:35 +0800222
AleX Pelosid6150182021-03-05 18:10:44 -0800223 if (!client)
224 return -EINVAL;
225
226 data = i2c_get_clientdata(client);
Ken Tsou8acade12020-07-09 03:17:35 +0800227 if (!data || !data->regmap)
228 return -ENXIO;
229
230 return max77729_pmic_readn(data, addr, val, len);
231}
232EXPORT_SYMBOL_GPL(max777x9_pmic_reg_read);
233
234int max777x9_pmic_reg_write(struct i2c_client *client,
235 u8 addr, const u8 *val, int len)
236{
AleX Pelosid6150182021-03-05 18:10:44 -0800237 struct max77729_pmic_data *data;
Ken Tsou8acade12020-07-09 03:17:35 +0800238
AleX Pelosid6150182021-03-05 18:10:44 -0800239 if (!client)
240 return -EINVAL;
241
242 data = i2c_get_clientdata(client);
Ken Tsou8acade12020-07-09 03:17:35 +0800243 if (!data || !data->regmap)
244 return -ENXIO;
245
246 return max77729_pmic_writen(data, addr, val, len);
247}
248EXPORT_SYMBOL_GPL(max777x9_pmic_reg_write);
249
250int max777x9_pmic_reg_update(struct i2c_client *client,
251 u8 reg, u8 mask, u8 value)
252{
AleX Pelosid6150182021-03-05 18:10:44 -0800253 struct max77729_pmic_data *data;
Ken Tsou8acade12020-07-09 03:17:35 +0800254
AleX Pelosid6150182021-03-05 18:10:44 -0800255 if (!client)
256 return -EINVAL;
257
258 data = i2c_get_clientdata(client);
Ken Tsou8acade12020-07-09 03:17:35 +0800259 if (!data || !data->regmap)
260 return -ENXIO;
261
262 return max77729_pmic_rmw8(data, reg, mask, value);
263}
264EXPORT_SYMBOL_GPL(max777x9_pmic_reg_update);
265
AleX Pelosid6150182021-03-05 18:10:44 -0800266
267int max777x9_pmic_get_id(struct i2c_client *client, u8 *id, u8 *rev)
268{
269 struct max77729_pmic_data *data;
270
271 if (!client)
272 return -EINVAL;
273
274 data = i2c_get_clientdata(client);
275 if (!data)
276 return -ENXIO;
277
278 *rev = data->rev_id;
279 *id = data->pmic_id;
280 return 0;
281}
282EXPORT_SYMBOL_GPL(max777x9_pmic_get_id);
283
AleX Pelosi90528cd2021-04-22 23:58:50 -0700284static int max77729_gpio_to_irq_mask(int offset, unsigned int *mask, unsigned int *val)
Badhri Jagan Sridharan991b7b52020-11-10 00:00:35 -0800285{
AleX Pelosi90528cd2021-04-22 23:58:50 -0700286 if (offset != MAX77759_GPIO5_OFF && offset != MAX77759_GPIO6_OFF)
Badhri Jagan Sridharan991b7b52020-11-10 00:00:35 -0800287 return -EINVAL;
Badhri Jagan Sridharan991b7b52020-11-10 00:00:35 -0800288
AleX Pelosi90528cd2021-04-22 23:58:50 -0700289 /* gpio5 is bit 0 of MAX77759_PMIC_UIC_INT1, gpio6 is bit 1 */
290 *mask = 1 << (offset - MAX77759_GPIO5_OFF);
291 *val = 1 << (offset - MAX77759_GPIO5_OFF) ;
Badhri Jagan Sridharan991b7b52020-11-10 00:00:35 -0800292 return 0;
293}
Ken Tsou8acade12020-07-09 03:17:35 +0800294
AleX Pelosi90528cd2021-04-22 23:58:50 -0700295static int max77729_gpio_clear_int(struct max77729_pmic_data *data, unsigned int offset)
296{
297 unsigned int mask, val;
298 int ret;
299
300 ret = max77729_gpio_to_irq_mask(offset, &mask, &val);
301 if (ret == 0)
302 ret = max77729_pmic_rmw8(data, MAX77759_PMIC_UIC_INT1, mask, val);
303
304 pr_debug("offset=%d clear int1 mask=%x val=%x (%d)\n",
305 offset, mask, val, ret);
306
307 return ret;
308}
309
310static irqreturn_t max777x9_pmic_route_irq(struct max77729_pmic_data *data,
311 int offset)
312{
313 int ret = 0, sub_irq;
314
315 /* NOTE: clearing before handle_nested_irq() assumes EDGE-type IRQ */
316 ret = max77729_gpio_clear_int(data, offset);
317 if (ret < 0)
318 pr_err("gpio%d cannot clear int1 (%d)", offset + 1, ret);
319
320 sub_irq = irq_find_mapping(data->gpio.irq.domain, offset);
321 pr_debug("offset=%d sub_irq=%d\n", offset, sub_irq);
322 if (sub_irq)
323 handle_nested_irq(sub_irq);
324
325 return ret;
326}
327
Ken Tsou8acade12020-07-09 03:17:35 +0800328/* this interrupt is read to clear, in max77759 it should be write to clear */
329static irqreturn_t max777x9_pmic_irq(int irq, void *ptr)
330{
331 struct max77729_pmic_data *data = ptr;
332 uint8_t intsrc = 0, uic_int[4];
333 int ret;
334
335 /* INTSRC is read to clear on MW and max77729f */
336 ret = max77729_pmic_rd8(data, MAX77729_PMIC_INTSRC, &intsrc);
337 if (ret < 0) {
338 dev_err_ratelimited(data->dev, "INTSRC: read error %d\n", ret);
339 return IRQ_NONE;
340 }
341
342 if (intsrc == 0)
343 return IRQ_NONE;
344
345 /* just clear for max77729f */
AleX Pelosi90528cd2021-04-22 23:58:50 -0700346 pr_debug("irq=%d INTSRC:%x\n", irq, intsrc);
Ken Tsou8acade12020-07-09 03:17:35 +0800347 if (data->pmic_id != MAX77759_PMIC_PMIC_ID_MW)
348 return IRQ_HANDLED;
349
350 /* UIC_INT are write to clear */
351 if (intsrc & MAX77759_PMIC_INTSRC_MAXQ_INT) {
352 ret = max77729_pmic_readn(data, MAX77759_PMIC_UIC_INT1,
353 uic_int, sizeof(uic_int));
354 if (ret < 0) {
355 dev_err_ratelimited(data->dev,
356 "UIC_INT1: read error %d\n", ret);
357 return IRQ_NONE;
358 }
359
360 /* TODO: implement / handle comms with maxq */
361 if (uic_int[0] & MAX77759_PMIC_UIC_INT1_APCMDRESI) {
362 maxq_irq(data->maxq);
363 max77729_pmic_wr8(data, MAX77759_PMIC_UIC_INT1,
364 MAX77759_PMIC_UIC_INT1_APCMDRESI);
365 }
Badhri Jagan Sridharan991b7b52020-11-10 00:00:35 -0800366
AleX Pelosi90528cd2021-04-22 23:58:50 -0700367 if (uic_int[0] & MAX77759_PMIC_UIC_INT1_GPIO5I)
368 max777x9_pmic_route_irq(data, MAX77759_GPIO5_OFF);
369 if (uic_int[0] & MAX77759_PMIC_UIC_INT1_GPIO6I)
370 max777x9_pmic_route_irq(data, MAX77759_GPIO6_OFF);
Ken Tsou8acade12020-07-09 03:17:35 +0800371 }
372
373 if (intsrc & MAX77759_PMIC_TOPSYS_INT_SYSUVLO_INT)
374 atomic_inc(&data->sysuvlo_cnt);
375
376 if (intsrc & MAX77759_PMIC_TOPSYS_INT_SYSOVLO_INT)
377 atomic_inc(&data->sysovlo_cnt);
378
379 if (intsrc & MAX77759_PMIC_INTSRC_TOPSYS_INT) {
380 uint8_t tsi;
381
382 ret = max77729_pmic_rd8(data, MAX77729_PMIC_TOPSYS_INT, &tsi);
383 if (ret < 0) {
384 dev_err_ratelimited(data->dev,
385 "TOPSYS_INT: read error %d\n", ret);
386 return IRQ_NONE;
387 }
388
389 ret = max77729_pmic_wr8(data, MAX77729_PMIC_TOPSYS_INT, tsi);
390 if (ret < 0) {
391 dev_err_ratelimited(data->dev,
392 "TOPSYS_INT:%x clr error %d\n", tsi, ret);
393 return IRQ_NONE;
394 }
395
396 pr_info("TOPSYS_INT:%x\n", tsi);
397
398 /* TODO: handle TSHDN_INT, SYSOVLO_INT, SYSUVLO_INT */
399 }
400
401 /* just clear CHG_INT, no FG intr for MW */
402
403 return IRQ_HANDLED;
404}
405
AleX Pelosi90528cd2021-04-22 23:58:50 -0700406/*
407 * Bootloader has everything masked clear this on boot
408 * GPIO irqs are enabled later
409 */
Ken Tsou8acade12020-07-09 03:17:35 +0800410static int max777x9_pmic_set_irqmask(struct max77729_pmic_data *data)
411{
412 int ret;
413
414 if (data->pmic_id == MAX77759_PMIC_PMIC_ID_MW) {
AleX Pelosi90528cd2021-04-22 23:58:50 -0700415 const u8 uic_mask[] = {0x7f, 0xff, 0xff, 0xff};
Badhri Jagan Sridharan991b7b52020-11-10 00:00:35 -0800416 u8 reg;
Ken Tsou8acade12020-07-09 03:17:35 +0800417
AleX Pelosi90528cd2021-04-22 23:58:50 -0700418 ret = max77729_pmic_rd8(data, MAX77759_PMIC_INTSRC, &reg);
Ken Tsou8acade12020-07-09 03:17:35 +0800419 if (ret < 0 || reg)
420 dev_info(data->dev, "INTSRC :%x (%d)\n", reg, ret);
AleX Pelosi90528cd2021-04-22 23:58:50 -0700421
422 ret = max77729_pmic_rd8(data, MAX77759_PMIC_TOPSYS_INT, &reg);
Ken Tsou8acade12020-07-09 03:17:35 +0800423 if (ret < 0 || reg)
424 dev_info(data->dev, "TOPSYS_INT :%x (%d)\n", reg, ret);
425
426 ret = max77729_pmic_wr8(data, MAX77759_PMIC_INTSRCMASK,
427 MAX77759_PMIC_INTSRCMASK_DEFAULT);
428
429 /* b/156527175, *_PMIC_TOPSYS_INT_MASK_SPR_7 is reserved */
430 ret |= max77729_pmic_rmw8(data, MAX77759_PMIC_TOPSYS_INT_MASK,
AleX Pelosi90528cd2021-04-22 23:58:50 -0700431 MAX77759_PMIC_TOPSYS_INT_MASK_MASK,
432 MAX77759_PMIC_TOPSYS_INT_MASK_DEFAULT);
433
434 /* clear all, unmask MAX77759_PMIC_UIC_INT1_APCMDRESI */
Ken Tsou8acade12020-07-09 03:17:35 +0800435 ret |= max77729_pmic_wr8(data, MAX77759_PMIC_UIC_INT1,
AleX Pelosi90528cd2021-04-22 23:58:50 -0700436 MAX77759_PMIC_UIC_INT1_GPIO5I |
437 MAX77759_PMIC_UIC_INT1_GPIO6I |
438 MAX77759_PMIC_UIC_INT1_APCMDRESI);
Ken Tsou8acade12020-07-09 03:17:35 +0800439 ret |= max77729_pmic_writen(data, MAX77759_PMIC_UIC_INT1_M,
440 uic_mask, sizeof(uic_mask));
441 } else {
442 ret = max77729_pmic_wr8(data, MAX77729_PMIC_INTSRCMASK,
443 MAX77729_PMIC_INTSRCMASK_DEFAULT);
444 ret |= max77729_pmic_wr8(data, MAX77729_PMIC_TOPSYS_INT_MASK,
445 MAX77729_PMIC_TOPSYS_INT_MASK_DEFAULT);
446 }
447
448 return ret ? -EIO : 0;
449}
450
451static int max77759_find_fg(struct max77729_pmic_data *data)
452{
453 struct device_node *dn;
454
455 if (data->fg_i2c_client)
456 return 0;
457
458 dn = of_parse_phandle(data->dev->of_node, "max77759,max_m5", 0);
459 if (!dn)
460 return -ENXIO;
461
462 data->fg_i2c_client = of_find_i2c_device_by_node(dn);
463 if (!data->fg_i2c_client)
464 return -EAGAIN;
465
466 return 0;
467}
468
Wasb Liu04663ef2020-11-20 17:48:59 +0800469#define NTC_CURVE_THRESHOLD 185
470#define NTC_CURVE_1_BASE 960
471#define NTC_CURVE_1_SHIFT 2
472#define NTC_CURVE_2_BASE 730
473#define NTC_CURVE_2_SHIFT 3
474
AleX Pelosi48b1a2d2021-06-28 13:11:50 -0700475/*
476 * WARNING: The FG will behave erratically when the recovery path fails.
477 */
Ken Tsou8acade12020-07-09 03:17:35 +0800478static int max77759_read_thm(struct max77729_pmic_data *data, int mux,
479 unsigned int *value)
480{
AleX Pelosi48b1a2d2021-06-28 13:11:50 -0700481 unsigned int ain0, config, check_config = 0;
482 u8 pmic_ctrl, check_pmic = 0;
Ken Tsou8acade12020-07-09 03:17:35 +0800483 int tmp, ret;
Ken Tsou8acade12020-07-09 03:17:35 +0800484
485 if (!data->fg_i2c_client)
486 return -EINVAL;
487
AleX Pelosi48b1a2d2021-06-28 13:11:50 -0700488 /* TODO: prevent the FG from loading the FG model */
489
490 /* set TEX=1 in Config 0x1D, make sure that TEN is enabled */
Ken Tsou8acade12020-07-09 03:17:35 +0800491 ret = max_m5_reg_read(data->fg_i2c_client, MAX77759_FG_CONFIG, &config);
492 if (ret == 0) {
AleX Pelosi48b1a2d2021-06-28 13:11:50 -0700493 const u16 val = config | MAX77759_FG_CONFIG_TEN | MAX77759_FG_CONFIG_TEX;
494
495 /* TEN should be enabled for this to work */
496 WARN_ON(!(config & MAX77759_FG_CONFIG_TEN));
Ken Tsou8acade12020-07-09 03:17:35 +0800497
498 ret = max_m5_reg_write(data->fg_i2c_client, MAX77759_FG_CONFIG,
499 val);
AleX Pelosi48b1a2d2021-06-28 13:11:50 -0700500
501 pr_info("%s: config:%x->%x (%d)\n", __func__, config, val, ret);
Ken Tsou8acade12020-07-09 03:17:35 +0800502 }
AleX Pelosi32892282020-09-11 02:29:20 -0700503 if (ret == -ENODEV) {
AleX Pelosi48b1a2d2021-06-28 13:11:50 -0700504 pr_err("%s: no support for max_m5 FG (%d)\n", __func__, ret);
AleX Pelosi32892282020-09-11 02:29:20 -0700505 *value = 25;
506 return 0;
507 } else if (ret < 0) {
AleX Pelosi48b1a2d2021-06-28 13:11:50 -0700508 pr_err("%s: cannot change FG Config (%d)\n", __func__, ret);
Ken Tsou8acade12020-07-09 03:17:35 +0800509 return -EIO;
510 }
511
512 /* set THMIO_MUX */
513 ret = max77729_pmic_rd8(data, MAX77759_PMIC_CONTROL_FG, &pmic_ctrl);
514 if (ret == 0) {
515 const u8 val = _pmic_control_fg_thmio_mux_set(pmic_ctrl, mux);
516
517 ret = max77729_pmic_wr8(data, MAX77759_PMIC_CONTROL_FG, val);
AleX Pelosi48b1a2d2021-06-28 13:11:50 -0700518
519 pr_info("%s: pmic_ctrl:%x->%x (%d)\n", __func__, pmic_ctrl, val, ret);
Ken Tsou8acade12020-07-09 03:17:35 +0800520 }
521
522 if (ret < 0) {
523 pr_err("%s: cannot change MUX config (%d)\n", __func__, ret);
524 goto restore_fg;
525 }
526
AleX Pelosi48b1a2d2021-06-28 13:11:50 -0700527 /* msleep is uninterruptible */
Ken Tsou8acade12020-07-09 03:17:35 +0800528 msleep(1500);
529
530 ret = max_m5_reg_read(data->fg_i2c_client, MAX77759_FG_AIN0, &ain0);
531 pr_debug("%s: AIN0=%d (%d)\n", __func__, ain0, ret);
AleX Pelosi48b1a2d2021-06-28 13:11:50 -0700532 if (ret < 0) {
533 pr_err("%s: cannot read AIN0 (%d)\n", __func__, ret);
534 } else if (mux == THMIO_MUX_USB_TEMP || mux == THMIO_MUX_BATT_PACK) {
Wasb Liu04663ef2020-11-20 17:48:59 +0800535 /* convert form 1.8V to 2.4V and get higher 10 bits */
536 const unsigned int conv_adc = ((ain0 * 1800) / 2400) >> 6;
537
538 /* Temp = (rawadc < 185)? (960-rawadc/4) : (730-rawadc/8) */
539 /* unit: 0.1 degree C */
540 if (conv_adc < NTC_CURVE_THRESHOLD)
541 *value = NTC_CURVE_1_BASE - ((conv_adc * 10) >> NTC_CURVE_1_SHIFT);
542 else
543 *value = NTC_CURVE_2_BASE - ((conv_adc * 10) >> NTC_CURVE_2_SHIFT);
544 } else {
545 /* AIN0 is ratiometric on THM, 0xffff = 100%, lsb is 2^-16 */
546 *value = (100000 * (unsigned long)ain0) / (0x10000 - ain0);
547 }
Ken Tsou8acade12020-07-09 03:17:35 +0800548
549 /* restore THMIO_MUX */
550 tmp = max77729_pmic_wr8(data, MAX77759_PMIC_CONTROL_FG, pmic_ctrl);
551 WARN_ON(tmp != 0);
552
AleX Pelosi48b1a2d2021-06-28 13:11:50 -0700553 /* And reset the pmic if cannot restore (b/191319560) */
554 tmp = max77729_pmic_rd8(data, MAX77759_PMIC_CONTROL_FG, &check_pmic);
555 if (tmp != 0 || pmic_ctrl != check_pmic) {
556 dev_err(data->dev, "Cannot restore TMUX ret=%d\n", tmp);
557 BUG_ON(tmp != 0 || pmic_ctrl != check_pmic);
558 }
559
Ken Tsou8acade12020-07-09 03:17:35 +0800560restore_fg:
AleX Pelosi48b1a2d2021-06-28 13:11:50 -0700561
562 /* Clear TEX=0 in Config, restore 0x1D (b/191319560) */
563 config &= ~MAX77759_FG_CONFIG_TEX;
Ken Tsou8acade12020-07-09 03:17:35 +0800564 tmp = max_m5_reg_write(data->fg_i2c_client, MAX77759_FG_CONFIG, config);
565 WARN_ON(tmp != 0);
566
AleX Pelosi48b1a2d2021-06-28 13:11:50 -0700567 /* And reset the FG if this fails (b/191319560) */
568 tmp = max_m5_reg_read(data->fg_i2c_client, MAX77759_FG_CONFIG, &check_config);
569 if (tmp != 0 || config != check_config) {
570 tmp = max17x0x_sw_reset(data->fg_i2c_client);
571 dev_err(data->dev, "Cannot restore FG Config, FG reset ret=%d\n", tmp);
572 BUG_ON(tmp != 0);
573 } else if (!(check_config & MAX77759_FG_CONFIG_TEN)) {
574 dev_warn(data->dev, "TEN bit is not set in Config=%x\n", check_config);
575 }
576
577 /* TODO: allow the FG to load the FG model */
578
579 pr_info("%s: check_pmic=%x check_config=%x (%d)\n", __func__,
580 check_pmic, check_config, ret);
581
Ken Tsou8acade12020-07-09 03:17:35 +0800582 return ret;
583}
584
Ted Lin855504f2020-11-23 14:44:12 +0800585/* THMIO_MUX=0 in CONTROL_FG (0x51) */
586int max77759_read_batt_conn(struct i2c_client *client, int *temp)
587{
588 struct max77729_pmic_data *data = i2c_get_clientdata(client);
589 unsigned int val;
590 int ret;
591
592 mutex_lock(&data->io_lock);
593 ret = max77759_find_fg(data);
594 if (ret == 0)
595 ret = max77759_read_thm(data, THMIO_MUX_BATT_PACK, &val);
596 mutex_unlock(&data->io_lock);
597
598 if (ret == 0) {
599 /* TODO: b/160737498 convert voltage to temperature */
600 *temp = val;
601 }
602
603 return ret;
604}
605EXPORT_SYMBOL_GPL(max77759_read_batt_conn);
606
Ken Tsou8acade12020-07-09 03:17:35 +0800607/* THMIO_MUX=1 in CONTROL_FG (0x51) */
608int max77759_read_usb_temp(struct i2c_client *client, int *temp)
609{
610 struct max77729_pmic_data *data = i2c_get_clientdata(client);
611 unsigned int val;
612 int ret;
613
614 mutex_lock(&data->io_lock);
615 ret = max77759_find_fg(data);
616 if (ret == 0)
617 ret = max77759_read_thm(data, THMIO_MUX_USB_TEMP, &val);
AleX Pelosi48b1a2d2021-06-28 13:11:50 -0700618 if (ret == 0)
Ken Tsou8acade12020-07-09 03:17:35 +0800619 *temp = val;
AleX Pelosi48b1a2d2021-06-28 13:11:50 -0700620 mutex_unlock(&data->io_lock);
Ken Tsou8acade12020-07-09 03:17:35 +0800621
622 return ret;
623}
624EXPORT_SYMBOL_GPL(max77759_read_usb_temp);
625
Ken Tsou8acade12020-07-09 03:17:35 +0800626/* THMIO_MUX=2 in CONTROL_FG (0x51) */
627int max77759_read_batt_id(struct i2c_client *client, unsigned int *id)
628{
629 struct max77729_pmic_data *data = i2c_get_clientdata(client);
AleX Pelosi48b1a2d2021-06-28 13:11:50 -0700630 unsigned int val;
631 int ret;
Ken Tsou8acade12020-07-09 03:17:35 +0800632
AleX Pelosi48b1a2d2021-06-28 13:11:50 -0700633 mutex_lock(&data->io_lock);
634 ret = max77759_find_fg(data);
635 if (ret == 0)
636 ret = max77759_read_thm(data, THMIO_MUX_BATT_ID, &val);
637 if (ret == 0)
638 *id = val;
639 mutex_unlock(&data->io_lock);
640
641 return 0;
Ken Tsou8acade12020-07-09 03:17:35 +0800642}
643EXPORT_SYMBOL_GPL(max77759_read_batt_id);
644
Ken Tsou8acade12020-07-09 03:17:35 +0800645/* must use repeated starts b/152373060 */
646static int max77729_pmic_read_id(struct i2c_client *i2c)
647{
648 struct i2c_msg xfer[2];
649 u8 reg = MAX77729_PMIC_ID;
650 u8 pmic_id;
651 int ret;
652
653 xfer[0].addr = i2c->addr;
654 xfer[0].flags = 0;
655 xfer[0].len = 1;
656 xfer[0].buf = &reg;
657
658 xfer[1].addr = i2c->addr;
659 xfer[1].flags = I2C_M_RD;
660 xfer[1].len = 1;
661 xfer[1].buf = &pmic_id;
662
663 ret = i2c_transfer(i2c->adapter, xfer, 2);
664 if (ret == 2)
665 return pmic_id;
666 return -EIO;
667}
668
AleX Pelosi48b1a2d2021-06-28 13:11:50 -0700669/* cahe the value */
670static int debug_batt_thm_id_get(void *d, u64 *val)
Ken Tsou8acade12020-07-09 03:17:35 +0800671{
672 struct max77729_pmic_data *data = d;
AleX Pelosi48b1a2d2021-06-28 13:11:50 -0700673 int ret, value;
Ken Tsou8acade12020-07-09 03:17:35 +0800674
AleX Pelosi48b1a2d2021-06-28 13:11:50 -0700675 ret = max77759_read_batt_id(data->pmic_i2c_client, &value);
Ken Tsou8acade12020-07-09 03:17:35 +0800676 if (ret == 0)
AleX Pelosi48b1a2d2021-06-28 13:11:50 -0700677 *val = value;
Ken Tsou8acade12020-07-09 03:17:35 +0800678 return ret;
679}
AleX Pelosi48b1a2d2021-06-28 13:11:50 -0700680DEFINE_SIMPLE_ATTRIBUTE(debug_batt_thm_id_fops, debug_batt_thm_id_get, NULL, "%llu\n");
Ken Tsou8acade12020-07-09 03:17:35 +0800681
Ted Lin855504f2020-11-23 14:44:12 +0800682static int debug_batt_thm_conn_get(void *d, u64 *val)
683{
684 struct max77729_pmic_data *data = d;
AleX Pelosi48b1a2d2021-06-28 13:11:50 -0700685 int ret, value;
Ted Lin855504f2020-11-23 14:44:12 +0800686
AleX Pelosi48b1a2d2021-06-28 13:11:50 -0700687 ret = max77759_read_batt_conn(data->pmic_i2c_client, &value);
Ted Lin855504f2020-11-23 14:44:12 +0800688 if (ret == 0)
AleX Pelosi48b1a2d2021-06-28 13:11:50 -0700689 *val = value;
Ted Lin855504f2020-11-23 14:44:12 +0800690
691 return ret;
692}
693DEFINE_SIMPLE_ATTRIBUTE(debug_batt_thm_conn_fops, debug_batt_thm_conn_get, NULL, "%llu\n");
694
Wasb Liu7830d712021-01-20 15:30:44 +0800695static int max777x9_pmic_debug_reg_read(void *d, u64 *val)
696{
697 struct max77729_pmic_data *data = d;
698 u8 reg = 0;
699 int ret;
700
701 ret = max77729_pmic_rd8(data, data->debug_reg_address, &reg);
702 if (ret)
703 return ret;
704 *val = reg;
705 return 0;
706}
707
708static int max777x9_pmic_debug_reg_write(void *d, u64 val)
709{
710 struct max77729_pmic_data *data = d;
711 u8 reg = (u8) val;
712
713 pr_warn("debug write reg 0x%x, 0x%x", data->debug_reg_address, reg);
714 return max77729_pmic_wr8(data, data->debug_reg_address, reg);
715}
716DEFINE_SIMPLE_ATTRIBUTE(debug_reg_rw_fops, max777x9_pmic_debug_reg_read,
717 max777x9_pmic_debug_reg_write, "%02llx\n");
718
Jenny Ho2c407222022-04-27 09:29:04 +0800719static ssize_t max777x9_pmic_debug_show_reg_all(struct file *filp, char __user *buf,
720 size_t count, loff_t *ppos)
721{
722 struct max77729_pmic_data *data = (struct max77729_pmic_data *)filp->private_data;
723 u32 reg_address;
724 u8 reg = 0;
725 char *tmp;
726 int ret = 0, len = 0;
727
728 if (!data->regmap) {
729 pr_err("Failed to read, no regmap\n");
730 return -EIO;
731 }
732
733 tmp = kmalloc(PAGE_SIZE, GFP_KERNEL);
734 if (!tmp)
735 return -ENOMEM;
736
737 for (reg_address = 0; reg_address <= 0xFF; reg_address++) {
738 /* reasonable registers */
739 if (!max77729_pmic_is_reg(data->dev, reg_address))
740 continue;
741
742 ret = max77729_pmic_rd8(data, reg_address, &reg);
743 if (ret < 0)
744 continue;
745
746 len += scnprintf(tmp + len, PAGE_SIZE - len, "%02x: %02x\n", reg_address, reg);
747 }
748
749 if (len > 0)
750 len = simple_read_from_buffer(buf, count, ppos, tmp, strlen(tmp));
751
752 kfree(tmp);
753
754 return len;
755}
756
757BATTERY_DEBUG_ATTRIBUTE(debug_all_reg_fops, max777x9_pmic_debug_show_reg_all, NULL);
758
Wasb Liuf19aa972020-11-13 23:36:08 +0800759static int max77759_pmic_storage_iter(int index, gbms_tag_t *tag, void *ptr)
760{
761 if (index < 0 || index > (GBMS_TAG_RRS7 - GBMS_TAG_RRS0))
762 return -ENOENT;
763
764 *tag = GBMS_TAG_RRS0 + index;
765 return 0;
766}
767
768static int max77759_pmic_storage_read(gbms_tag_t tag, void *buff, size_t size, void *ptr)
769{
770 const int base = MAX77759_STORAGE_BASE + tag - GBMS_TAG_RRS0;
771 struct max77729_pmic_data *data = ptr;
772 int ret;
773
774 if (tag < GBMS_TAG_RRS0 || tag > GBMS_TAG_RRS7)
775 return -ENOENT;
776 if ((tag + size - 1) > GBMS_TAG_RRS7)
777 return -ERANGE;
778
779 ret = max77729_pmic_readn(data, base, buff, size);
780 if (ret < 0)
781 ret = -EIO;
782 return ret;
783}
784
785static int max77759_pmic_storage_write(gbms_tag_t tag, const void *buff, size_t size, void *ptr)
786{
787 const int base = MAX77759_STORAGE_BASE + tag - GBMS_TAG_RRS0;
788 struct max77729_pmic_data *data = ptr;
789 int ret;
790
791 if (tag < GBMS_TAG_RRS0 || tag > GBMS_TAG_RRS7)
792 return -ENOENT;
793 if ((tag + size - 1) > GBMS_TAG_RRS7)
794 return -ERANGE;
795
796 ret = max77729_pmic_writen(data, base, buff, size);
797 if (ret < 0)
798 ret = -EIO;
799 return ret;
800}
801
802static struct gbms_storage_desc max77759_pmic_storage_dsc = {
803 .iter = max77759_pmic_storage_iter,
804 .read = max77759_pmic_storage_read,
805 .write = max77759_pmic_storage_write,
806};
807
808#define STORAGE_INIT_DELAY_MS 100
809#define STORAGE_INIT_MAX_RETRY 3
810static void max777x9_pmic_storage_init_work(struct work_struct *work)
811{
812 struct max77729_pmic_data *data = container_of(work, struct max77729_pmic_data,
813 storage_init_work.work);
814 static int retry_cnt;
815 int ret = 0;
816
817 ret = gbms_storage_register(&max77759_pmic_storage_dsc,
818 "max777x9_pmic_storage", data);
819
820 if (ret == 0) {
821 pr_info("register storage done\n");
822 } else if (retry_cnt >= STORAGE_INIT_MAX_RETRY) {
823 pr_info("register storage:%d retry_cnt=%d, stop retry.\n", ret, retry_cnt);
824 } else {
825 schedule_delayed_work(&data->storage_init_work,
826 msecs_to_jiffies(STORAGE_INIT_DELAY_MS));
827 retry_cnt++;
828 }
829
830 return;
831}
832
Ken Tsou8acade12020-07-09 03:17:35 +0800833static int dbg_init_fs(struct max77729_pmic_data *data)
834{
835 data->de = debugfs_create_dir("max77729_pmic", 0);
836 if (IS_ERR_OR_NULL(data->de))
837 return -EINVAL;
838
AleX Pelosi48b1a2d2021-06-28 13:11:50 -0700839 debugfs_create_atomic_t("sysuvlo_cnt", 0644, data->de, &data->sysuvlo_cnt);
840 debugfs_create_atomic_t("sysovlo_cnt", 0644, data->de, &data->sysovlo_cnt);
Ken Tsou8acade12020-07-09 03:17:35 +0800841
842 debugfs_create_file("batt_id", 0400, data->de, data,
AleX Pelosi48b1a2d2021-06-28 13:11:50 -0700843 &debug_batt_thm_id_fops);
Ted Lin855504f2020-11-23 14:44:12 +0800844 debugfs_create_file("batt_thm_conn", 0400, data->de, data,
845 &debug_batt_thm_conn_fops);
Ken Tsou8acade12020-07-09 03:17:35 +0800846
Wasb Liu7830d712021-01-20 15:30:44 +0800847 debugfs_create_u32("address", 0600, data->de, &data->debug_reg_address);
848 debugfs_create_file("data", 0600, data->de, data, &debug_reg_rw_fops);
Jenny Ho2c407222022-04-27 09:29:04 +0800849 debugfs_create_file("registers", 0444, data->de, data, &debug_all_reg_fops);
Wasb Liu7830d712021-01-20 15:30:44 +0800850
Ken Tsou8acade12020-07-09 03:17:35 +0800851 return 0;
852}
853
AleX Pelosi6852a072020-09-08 19:05:56 -0700854#if IS_ENABLED(CONFIG_GPIOLIB)
Ken Tsou8acade12020-07-09 03:17:35 +0800855
AleX Pelosi90528cd2021-04-22 23:58:50 -0700856/* offset is gpionum - 1 */
Ken Tsou8acade12020-07-09 03:17:35 +0800857static int max77759_gpio_get_direction(struct gpio_chip *chip,
858 unsigned int offset)
859{
860 struct max77729_pmic_data *data = gpiochip_get_data(chip);
861 int rc;
862 uint8_t val;
863
864 if ((offset < MAX77759_MIN_GPIO_OFF) || (offset > MAX77759_MAX_GPIO_OFF))
865 return -EINVAL;
866
867 rc = maxq_gpio_control_read(data->maxq, &val);
868 if (rc < 0) {
869 dev_err(data->dev, "opcode read 0x23 failed\n");
870 return rc;
871 }
872
873 if (offset == MAX77759_GPIO5_OFF)
874 return !(val & MAX77759_GPIO5_DIR_MASK);
875
876 return !(val & MAX77759_GPIO6_DIR_MASK);
877}
878
AleX Pelosi90528cd2021-04-22 23:58:50 -0700879/* offset is gpionum - 1 */
Ken Tsou8acade12020-07-09 03:17:35 +0800880static int max77759_gpio_get(struct gpio_chip *chip, unsigned int offset)
881{
882 struct max77729_pmic_data *data = gpiochip_get_data(chip);
883 int rc;
884 uint8_t val;
885
886 if ((offset < MAX77759_MIN_GPIO_OFF) || (offset > MAX77759_MAX_GPIO_OFF))
887 return -EINVAL;
888
889 rc = maxq_gpio_control_read(data->maxq, &val);
890 if (rc < 0) {
891 dev_err(data->dev, "opcode read 0x23 failed\n");
892 return rc;
893 }
894
895 if (offset == MAX77759_GPIO5_OFF)
896 return !!(val & MAX77759_GPIO5_VAL_MASK);
897
898 return !!(val & MAX77759_GPIO6_VAL_MASK);
899}
900
AleX Pelosi90528cd2021-04-22 23:58:50 -0700901/* offset is gpionum - 1 */
Ken Tsou8acade12020-07-09 03:17:35 +0800902static void max77759_gpio_set(struct gpio_chip *chip,
903 unsigned int offset, int value)
904{
905 struct max77729_pmic_data *data = gpiochip_get_data(chip);
906 int rc;
907 uint8_t val;
908 uint8_t new_val;
909 uint8_t dir;
910
911 if ((offset < MAX77759_MIN_GPIO_OFF) || (offset > MAX77759_MAX_GPIO_OFF))
912 return;
913
914 rc = maxq_gpio_control_read(data->maxq, &val);
915 if (rc < 0) {
916 dev_err(data->dev, "opcode read 0x23 failed\n");
917 return;
918 }
919
920 if (offset == MAX77759_GPIO5_OFF) {
921 dir = !(val & MAX77759_GPIO5_DIR_MASK);
922 if (dir != GPIOF_DIR_OUT) {
923 dev_err(data->dev, "not output\n");
924 return;
925 }
926 new_val = val & ~MAX77759_GPIO5_VAL_MASK;
927 new_val |= MAX77759_GPIO5_VAL(value);
928 } else { /* MAX77759_GPIO6_OFF */
929 dir = !(val & MAX77759_GPIO6_DIR_MASK);
930 if (dir != GPIOF_DIR_OUT) {
931 dev_err(data->dev, "not output\n");
932 return;
933 }
934 new_val = val & ~MAX77759_GPIO6_VAL_MASK;
935 new_val |= MAX77759_GPIO6_VAL(value);
936 }
937
938 if (new_val != val) {
939 rc = maxq_gpio_control_write(data->maxq, new_val);
940 if (rc < 0) {
941 dev_err(data->dev, "opcode write 0x24 failed\n");
942 return;
943 }
944 }
Ken Tsou8acade12020-07-09 03:17:35 +0800945}
946
AleX Pelosi90528cd2021-04-22 23:58:50 -0700947/* offset is gpionum - 1 */
Ken Tsou8acade12020-07-09 03:17:35 +0800948static int max77759_gpio_direction_input(struct gpio_chip *chip,
949 unsigned int offset)
950{
951 struct max77729_pmic_data *data = gpiochip_get_data(chip);
952 int rc;
953 uint8_t val;
954 uint8_t new_val;
955
956 if ((offset < MAX77759_MIN_GPIO_OFF) || (offset > MAX77759_MAX_GPIO_OFF))
957 return -EINVAL;
958
959 rc = maxq_gpio_control_read(data->maxq, &val);
960 if (rc < 0) {
961 dev_err(data->dev, "opcode read 0x23 failed\n");
962 return rc;
963 }
964
965 if (offset == MAX77759_GPIO5_OFF) {
966 new_val = val & ~MAX77759_GPIO5_DIR_MASK;
967 new_val |= MAX77759_GPIO5_DIR(MAX77759_GPIO_DIR_IN);
968 } else { /* MAX77759_GPIO6_OFF */
969 new_val = val & ~MAX77759_GPIO6_DIR_MASK;
970 new_val |= MAX77759_GPIO6_DIR(MAX77759_GPIO_DIR_IN);
971 }
972
973 if (new_val != val) {
974 rc = maxq_gpio_control_write(data->maxq, new_val);
975 if (rc < 0) {
976 dev_err(data->dev, "opcode write 0x24 failed\n");
977 return rc;
978 }
979 }
980
981 return 0;
982}
983
AleX Pelosi90528cd2021-04-22 23:58:50 -0700984/* offset is gpionum - 1 */
Ken Tsou8acade12020-07-09 03:17:35 +0800985static int max77759_gpio_direction_output(struct gpio_chip *chip,
986 unsigned int offset, int value)
987{
988 struct max77729_pmic_data *data = gpiochip_get_data(chip);
989 int rc;
990 uint8_t val;
991 uint8_t new_val;
992
993 if ((offset < MAX77759_MIN_GPIO_OFF) || (offset > MAX77759_MAX_GPIO_OFF))
994 return -EINVAL;
995
996 rc = maxq_gpio_control_read(data->maxq, &val);
997 if (rc < 0) {
998 dev_err(data->dev, "opcode read 0x23 failed\n");
999 return rc;
1000 }
1001
1002 if (offset == MAX77759_GPIO5_OFF) {
1003 new_val = val & ~MAX77759_GPIO5_DIR_MASK;
1004 new_val |= MAX77759_GPIO5_DIR(MAX77759_GPIO_DIR_OUT);
1005 } else { /* MAX77759_GPIO6_OFF */
1006 new_val = val & ~MAX77759_GPIO6_DIR_MASK;
1007 new_val |= MAX77759_GPIO6_DIR(MAX77759_GPIO_DIR_OUT);
1008 }
1009
1010 if (new_val != val) {
1011 rc = maxq_gpio_control_write(data->maxq, new_val);
1012 if (rc < 0) {
1013 dev_err(data->dev, "opcode write 0x24 failed\n");
1014 return rc;
1015 }
1016 }
1017
1018 return 0;
1019}
AleX Pelosi90528cd2021-04-22 23:58:50 -07001020
1021/* d->hwirq is same as offset */
1022static void max77729_gpio_irq_mask(struct irq_data *d)
1023{
1024 struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
1025 struct max77729_pmic_data *data = gpiochip_get_data(gc);
1026
1027 data->irq_mask |= 1 << d->hwirq;
1028 data->irq_mask_u |= 1 << d->hwirq;
1029}
1030
1031static void max77729_gpio_irq_unmask(struct irq_data *d)
1032{
1033 struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
1034 struct max77729_pmic_data *data = gpiochip_get_data(gc);
1035
1036 data->irq_mask &= ~(1 << d->hwirq);
1037 data->irq_mask_u |= 1 << d->hwirq;
1038}
1039
1040static void max77729_gpio_irq_enable(struct irq_data *d)
1041{
1042 max77729_gpio_irq_unmask(d);
1043}
1044
1045static void max77729_gpio_irq_disable(struct irq_data *d)
1046{
1047 max77729_gpio_irq_mask(d);
1048}
1049
1050/* called in atomic context */
1051static int max77729_gpio_set_irq_type(struct irq_data *d, unsigned int type)
1052{
1053 struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
1054 struct max77729_pmic_data *data = gpiochip_get_data(gc);
1055 const int index = d->hwirq - MAX77759_GPIO5_OFF;
1056
1057 switch (type) {
1058 case IRQF_TRIGGER_FALLING:
1059 data->irq_trig_falling[index] = 1;
1060 break;
1061 case IRQF_TRIGGER_RISING:
1062 data->irq_trig_falling[index] = 0;
1063 break;
1064 default:
1065 return -EINVAL;
1066 }
1067
1068 data->irq_trig_u |= 1 << d->hwirq;
1069 return 0;
1070}
1071
1072static void max77729_gpio_bus_lock(struct irq_data *d)
1073{
1074 struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
1075 struct max77729_pmic_data *data = gpiochip_get_data(gc);
1076
1077 mutex_lock(&data->irq_lock);
1078}
1079
1080static int max77729_gpio_bus_irq_update_trig(struct max77729_pmic_data *data,
1081 int offset, int trig)
1082{
1083 int ret;
1084
1085 /* direction works with offset, trigger works with gpio number */
1086 ret = max77759_gpio_direction_input(&data->gpio, offset);
1087 if (ret == 0)
1088 ret = maxq_gpio_trigger_write(data->maxq, offset + 1, trig);
1089
1090 pr_debug("gpio%d: trig=%d (%d)\n", offset + 1, trig, ret);
1091
1092 return ret;
1093}
1094
1095static int max77729_gpio_bus_irq_update_mask(struct max77729_pmic_data *data,
1096 int offset, int value)
1097{
1098 unsigned int mask = 0, val = 0;
1099 int ret;
1100
1101 ret = max77729_gpio_to_irq_mask(offset, &mask, &val);
1102 if (ret == 0)
1103 ret = max77729_pmic_rmw8(data, MAX77759_PMIC_UIC_INT1_M, mask,
1104 value ? val : 0);
1105 if (ret < 0) {
1106 dev_err(data->dev, "gpio%d: cannot change mask=%x to %x (%d)\n",
1107 offset + 1, mask, value ? val : 0, ret);
1108 return ret;
1109 }
1110
1111 pr_debug("gpio%d: value=%d mask=%x, val=%x (%d)\n",
1112 offset +1, value, mask, val, ret);
1113
1114 return 0;
1115}
1116
1117/* cannot call any maxq function in atomic */
1118static void max77729_gpio_bus_sync_unlock(struct irq_data *d)
1119{
1120 struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
1121 struct max77729_pmic_data *data = gpiochip_get_data(gc);
1122 unsigned int offset, value;
1123
1124 while (data->irq_trig_u) {
1125 offset = __ffs(data->irq_trig_u);
1126 value = data->irq_trig_falling[offset - MAX77759_GPIO5_OFF];
1127
1128 max77729_gpio_bus_irq_update_trig(data, offset, value);
1129 data->irq_trig_u &= ~(1 << offset);
1130 }
1131
1132 while (data->irq_mask_u) {
1133 offset = __ffs(data->irq_mask_u);
1134 value = data->irq_mask & (1 << offset);
1135
1136 max77729_gpio_bus_irq_update_mask(data, offset, value);
1137 data->irq_mask_u &= ~(1 << offset);
1138 }
1139
1140 mutex_unlock(&data->irq_lock);
1141}
1142
1143/* bits 4 and 5 */
1144static void max77729_gpio_set_irq_valid_mask(struct gpio_chip *chip,
1145 unsigned long *valid_mask,
1146 unsigned int ngpios)
1147{
1148 bitmap_clear(valid_mask, 0, ngpios);
1149 *valid_mask = (1 << MAX77759_GPIO5_OFF) | (1 << MAX77759_GPIO6_OFF);
1150}
1151
1152/* only support 5 and 6, 5 is output */
1153static int max77729_gpio_irq_init_hw(struct gpio_chip *gc)
1154{
1155 struct max77729_pmic_data *data = gpiochip_get_data(gc);
1156 const u8 mask_gpio = MAX77759_PMIC_UIC_INT1_GPIO5I |
1157 MAX77759_PMIC_UIC_INT1_GPIO6I;
1158 int ret;
1159
1160 /* mask both */
1161 ret = max77729_pmic_rmw8(data, MAX77759_PMIC_UIC_INT1_M,
1162 mask_gpio, mask_gpio);
1163 if (ret < 0)
1164 dev_err(data->dev, "cannot mask IRQs\n");
1165
1166 /* ...and clear both */
1167 ret = max77729_pmic_wr8(data, MAX77759_PMIC_UIC_INT1,
1168 MAX77759_PMIC_UIC_INT1_GPIO5I |
1169 MAX77759_PMIC_UIC_INT1_GPIO6I);
1170 if (ret < 0)
1171 dev_err(data->dev, "cannot clear IRQs\n");
1172
1173 return 0;
1174}
1175static struct irq_chip max77729_gpio_irq_chip = {
1176 .name = "max777x9_irq",
1177 .irq_enable = max77729_gpio_irq_enable,
1178 .irq_disable = max77729_gpio_irq_disable,
1179 .irq_mask = max77729_gpio_irq_mask,
1180 .irq_unmask = max77729_gpio_irq_unmask,
1181 .irq_set_type =max77729_gpio_set_irq_type,
1182 .irq_bus_lock = max77729_gpio_bus_lock,
1183 .irq_bus_sync_unlock = max77729_gpio_bus_sync_unlock,
1184};
1185
Ken Tsou8acade12020-07-09 03:17:35 +08001186#endif
1187
AleX Pelosi90528cd2021-04-22 23:58:50 -07001188/* ----------------------------------------------------------------------- */
1189
1190
Ken Tsou8acade12020-07-09 03:17:35 +08001191static int max77729_pmic_probe(struct i2c_client *client,
1192 const struct i2c_device_id *id)
1193{
1194 struct device *dev = &client->dev;
1195 struct max77729_pmic_data *data;
1196 int irq_gpio, pmic_id, ret =0;
1197
1198 pmic_id = max77729_pmic_read_id(client);
1199 if (pmic_id < 0)
1200 return -ENODEV;
1201 if (pmic_id == MAX77759_PMIC_PMIC_ID_MW)
1202 max777x9_pmic_regmap_cfg.max_register = 0xe0;
1203
1204 data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
1205 if (!data)
1206 return -ENOMEM;
1207
1208 data->dev = dev;
1209 data->pmic_id = pmic_id;
1210 data->batt_id = -1;
1211 mutex_init(&data->io_lock);
1212 atomic_set(&data->sysuvlo_cnt, 0);
1213 atomic_set(&data->sysovlo_cnt, 0);
1214 i2c_set_clientdata(client, data);
Badhri Jagan Sridharan991b7b52020-11-10 00:00:35 -08001215 data->pmic_i2c_client = client;
Ken Tsou8acade12020-07-09 03:17:35 +08001216
Wasb Liuf19aa972020-11-13 23:36:08 +08001217 INIT_DELAYED_WORK(&data->storage_init_work, max777x9_pmic_storage_init_work);
1218
Ken Tsou8acade12020-07-09 03:17:35 +08001219 data->regmap = devm_regmap_init_i2c(client, &max777x9_pmic_regmap_cfg);
1220 if (IS_ERR(data->regmap)) {
1221 dev_err(dev, "Failed to initialize regmap\n");
1222 return -EINVAL;
1223 }
1224
AleX Pelosicb944302020-12-07 12:17:14 -08001225 if (pmic_id == MAX77759_PMIC_PMIC_ID_MW) {
1226 const int poll_en = of_property_read_bool(dev->of_node,
1227 "goog,maxq-poll");
AleX Pelosi48b1a2d2021-06-28 13:11:50 -07001228 u8 pmic_ctrl;
1229
1230
AleX Pelosicb944302020-12-07 12:17:14 -08001231 data->maxq = maxq_init(dev, data->regmap, poll_en);
1232 if (IS_ERR_OR_NULL(data->maxq)) {
1233 dev_err(dev, "Maxq init failed!\n");
1234 ret = PTR_ERR(data->maxq);
1235 }
AleX Pelosi48b1a2d2021-06-28 13:11:50 -07001236
1237 ret = max77729_pmic_rd8(data, MAX77759_PMIC_CONTROL_FG, &pmic_ctrl);
1238 WARN_ON(ret != 0 ||((pmic_ctrl & MAX77759_PMIC_CONTROL_FG_THMIO_MUX_MASK)
1239 != THMIO_MUX_BATT_PACK));
1240 if (ret == 0) {
1241 const u8 val = _pmic_control_fg_thmio_mux_set(pmic_ctrl,
1242 THMIO_MUX_BATT_PACK);
1243
1244 ret = max77729_pmic_wr8(data, MAX77759_PMIC_CONTROL_FG, val);
1245 WARN_ON(ret != 0);
1246 }
AleX Pelosicb944302020-12-07 12:17:14 -08001247 }
1248
Ken Tsou8acade12020-07-09 03:17:35 +08001249 irq_gpio = of_get_named_gpio(dev->of_node, "max777x9,irq-gpio", 0);
1250 if (irq_gpio < 0) {
1251 dev_err(dev, "irq is not defined\n");
1252 } else {
1253 client->irq = gpio_to_irq(irq_gpio);
1254
AleX Pelosi90528cd2021-04-22 23:58:50 -07001255 /* NOTE: all interrupts are masked here */
Ken Tsou8acade12020-07-09 03:17:35 +08001256 ret = devm_request_threaded_irq(data->dev, client->irq, NULL,
1257 max777x9_pmic_irq,
1258 IRQF_TRIGGER_LOW |
1259 IRQF_SHARED |
1260 IRQF_ONESHOT,
1261 "max777x9_pmic",
1262 data);
1263 if (ret < 0) {
1264 dev_err(dev, "failed get irq thread\n");
1265 } else {
1266 /* force clear pending before unmasking */
1267 max777x9_pmic_irq(0, data);
1268
AleX Pelosi90528cd2021-04-22 23:58:50 -07001269 /* NOTE: only enable the maxq interrupt */
Ken Tsou8acade12020-07-09 03:17:35 +08001270 ret = max777x9_pmic_set_irqmask(data);
1271 if (ret < 0)
1272 dev_err(dev, "failed to apply irq mask\n");
1273 }
1274 }
1275
AleX Pelosi7c542032020-09-11 03:29:00 -07001276 ret = dbg_init_fs(data);
1277 if (ret < 0)
1278 dev_err(dev, "Failed to initialize debug fs\n");
1279
1280 if (pmic_id == MAX77759_PMIC_PMIC_ID_MW) {
Wasb Liuf19aa972020-11-13 23:36:08 +08001281 u8 rev_reg;
1282 int rc = 0;
1283
1284 rc = max77729_pmic_rd8(data, MAX77759_PMIC_PMIC_REVISION, &rev_reg);
1285 if (rc < 0) {
1286 dev_err(dev, "Failed to read revision\n");
1287 data->rev_id = 0;
1288 } else {
1289 data->rev_id = _pmic_pmic_revision_rev_get(rev_reg);
1290 }
1291
AleX Pelosid6150182021-03-05 18:10:44 -08001292 if (data->rev_id == MAX77759_PMIC_REV_A0)
Wasb Liuf19aa972020-11-13 23:36:08 +08001293 schedule_delayed_work(&data->storage_init_work, 0);
1294 }
1295
AleX Pelosi6852a072020-09-08 19:05:56 -07001296#if IS_ENABLED(CONFIG_GPIOLIB)
AleX Pelosi90528cd2021-04-22 23:58:50 -07001297 mutex_init(&data->irq_lock);
1298
Ken Tsou8acade12020-07-09 03:17:35 +08001299 if (pmic_id == MAX77759_PMIC_PMIC_ID_MW) {
AleX Pelosi90528cd2021-04-22 23:58:50 -07001300 struct gpio_irq_chip *girq = &data->gpio.irq;
1301
AleX Pelosi6852a072020-09-08 19:05:56 -07001302 /* Setup GPIO controller */
Ken Tsou8acade12020-07-09 03:17:35 +08001303 data->gpio.owner = THIS_MODULE;
1304 data->gpio.parent = dev;
1305 data->gpio.label = "max777x9_gpio";
1306 data->gpio.get_direction = max77759_gpio_get_direction;
1307 data->gpio.direction_input = max77759_gpio_direction_input;
1308 data->gpio.direction_output = max77759_gpio_direction_output;
1309 data->gpio.get = max77759_gpio_get;
1310 data->gpio.set = max77759_gpio_set;
Ken Tsou8acade12020-07-09 03:17:35 +08001311 data->gpio.ngpio = MAX77759_NUM_GPIOS;
1312 data->gpio.can_sleep = true;
AleX Pelosi90528cd2021-04-22 23:58:50 -07001313 data->gpio.base = -1;
Ken Tsou8acade12020-07-09 03:17:35 +08001314 data->gpio.of_node = of_find_node_by_name(dev->of_node,
AleX Pelosi90528cd2021-04-22 23:58:50 -07001315 data->gpio.label);
Ken Tsou8acade12020-07-09 03:17:35 +08001316 if (!data->gpio.of_node)
AleX Pelosi90528cd2021-04-22 23:58:50 -07001317 dev_err(dev, "Failed to find %s DT node\n", data->gpio.label);
1318
1319 /* check regmap-irq */
1320 girq->chip = &max77729_gpio_irq_chip;
1321 girq->default_type = IRQ_TYPE_NONE;
1322 girq->handler = handle_simple_irq;
1323 girq->parent_handler = NULL;
1324 girq->num_parents = 0;
1325 girq->parents = NULL;
1326 girq->threaded = true;
1327 girq->init_hw = max77729_gpio_irq_init_hw;
1328 girq->init_valid_mask = max77729_gpio_set_irq_valid_mask;
1329 girq->first = 0;
Ken Tsou8acade12020-07-09 03:17:35 +08001330
1331 ret = devm_gpiochip_add_data(dev, &data->gpio, data);
1332 if (ret)
1333 dev_err(dev, "Failed to initialize gpio chip\n");
Badhri Jagan Sridharan991b7b52020-11-10 00:00:35 -08001334
Ken Tsou8acade12020-07-09 03:17:35 +08001335 }
1336#endif
1337
Wasb Liuf19aa972020-11-13 23:36:08 +08001338 dev_info(dev, "probe_done pmic_id = %x, rev_id= %x\n", pmic_id, data->rev_id);
Ken Tsou8acade12020-07-09 03:17:35 +08001339 return ret;
1340}
1341
1342static int max77729_pmic_remove(struct i2c_client *client)
1343{
1344 struct max77729_pmic_data *data = i2c_get_clientdata(client);
1345
1346 maxq_remove(data->maxq);
1347 return 0;
1348}
1349
1350static const struct of_device_id max77729_pmic_of_match_table[] = {
1351 { .compatible = "maxim,max77729pmic" },
1352 { .compatible = "maxim,max77759pmic" },
1353 {},
1354};
1355MODULE_DEVICE_TABLE(of, max77729_pmic_of_match_table);
1356
1357static const struct i2c_device_id max77729_pmic_id[] = {
1358 {"max77729_pmic", 0},
1359 {}
1360};
1361MODULE_DEVICE_TABLE(i2c, max77729_pmic_id);
1362
1363static struct i2c_driver max77729_pmic_i2c_driver = {
1364 .driver = {
1365 .name = "max777x9-pmic",
1366 .owner = THIS_MODULE,
1367 .of_match_table = max77729_pmic_of_match_table,
1368 },
1369 .id_table = max77729_pmic_id,
1370 .probe = max77729_pmic_probe,
1371 .remove = max77729_pmic_remove,
1372};
1373
1374module_i2c_driver(max77729_pmic_i2c_driver);
1375MODULE_DESCRIPTION("Maxim 77729 PMIC driver");
1376MODULE_LICENSE("GPL");