1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | /* |
3 | * Maxim MAX14656 / AL32 USB Charger Detector driver |
4 | * |
5 | * Copyright (C) 2014 LG Electronics, Inc |
6 | * Copyright (C) 2016 Alexander Kurz <akurz@blala.de> |
7 | * |
8 | * Components from Maxim AL32 Charger detection Driver for MX50 Yoshi Board |
9 | * Copyright (C) Amazon Technologies Inc. All rights reserved. |
10 | * Manish Lachwani (lachwani@lab126.com) |
11 | */ |
12 | #include <linux/module.h> |
13 | #include <linux/init.h> |
14 | #include <linux/delay.h> |
15 | #include <linux/i2c.h> |
16 | #include <linux/interrupt.h> |
17 | #include <linux/mod_devicetable.h> |
18 | #include <linux/slab.h> |
19 | #include <linux/workqueue.h> |
20 | #include <linux/power_supply.h> |
21 | #include <linux/devm-helpers.h> |
22 | |
23 | #define MAX14656_MANUFACTURER "Maxim Integrated" |
24 | #define MAX14656_NAME "max14656" |
25 | |
26 | #define MAX14656_DEVICE_ID 0x00 |
27 | #define MAX14656_INTERRUPT_1 0x01 |
28 | #define MAX14656_INTERRUPT_2 0x02 |
29 | #define MAX14656_STATUS_1 0x03 |
30 | #define MAX14656_STATUS_2 0x04 |
31 | #define MAX14656_INTMASK_1 0x05 |
32 | #define MAX14656_INTMASK_2 0x06 |
33 | #define MAX14656_CONTROL_1 0x07 |
34 | #define MAX14656_CONTROL_2 0x08 |
35 | #define MAX14656_CONTROL_3 0x09 |
36 | |
37 | #define DEVICE_VENDOR_MASK 0xf0 |
38 | #define DEVICE_REV_MASK 0x0f |
39 | #define INT_EN_REG_MASK BIT(4) |
40 | #define CHG_TYPE_INT_MASK BIT(0) |
41 | #define STATUS1_VB_VALID_MASK BIT(4) |
42 | #define STATUS1_CHG_TYPE_MASK 0xf |
43 | #define INT1_DCD_TIMEOUT_MASK BIT(7) |
44 | #define CONTROL1_DEFAULT 0x0d |
45 | #define CONTROL1_INT_EN BIT(4) |
46 | #define CONTROL1_INT_ACTIVE_HIGH BIT(5) |
47 | #define CONTROL1_EDGE BIT(7) |
48 | #define CONTROL2_DEFAULT 0x8e |
49 | #define CONTROL2_ADC_EN BIT(0) |
50 | #define CONTROL3_DEFAULT 0x8d |
51 | |
52 | enum max14656_chg_type { |
53 | MAX14656_NO_CHARGER = 0, |
54 | MAX14656_SDP_CHARGER, |
55 | MAX14656_CDP_CHARGER, |
56 | MAX14656_DCP_CHARGER, |
57 | MAX14656_APPLE_500MA_CHARGER, |
58 | MAX14656_APPLE_1A_CHARGER, |
59 | MAX14656_APPLE_2A_CHARGER, |
60 | MAX14656_SPECIAL_500MA_CHARGER, |
61 | MAX14656_APPLE_12W, |
62 | MAX14656_CHARGER_LAST |
63 | }; |
64 | |
65 | static const struct max14656_chg_type_props { |
66 | enum power_supply_type type; |
67 | } chg_type_props[] = { |
68 | { POWER_SUPPLY_TYPE_UNKNOWN }, |
69 | { POWER_SUPPLY_TYPE_USB }, |
70 | { POWER_SUPPLY_TYPE_USB_CDP }, |
71 | { POWER_SUPPLY_TYPE_USB_DCP }, |
72 | { POWER_SUPPLY_TYPE_USB_DCP }, |
73 | { POWER_SUPPLY_TYPE_USB_DCP }, |
74 | { POWER_SUPPLY_TYPE_USB_DCP }, |
75 | { POWER_SUPPLY_TYPE_USB_DCP }, |
76 | { POWER_SUPPLY_TYPE_USB }, |
77 | }; |
78 | |
79 | struct max14656_chip { |
80 | struct i2c_client *client; |
81 | struct power_supply *detect_psy; |
82 | struct power_supply_desc psy_desc; |
83 | struct delayed_work irq_work; |
84 | |
85 | int irq; |
86 | int online; |
87 | }; |
88 | |
89 | static int max14656_read_reg(struct i2c_client *client, int reg, u8 *val) |
90 | { |
91 | s32 ret; |
92 | |
93 | ret = i2c_smbus_read_byte_data(client, command: reg); |
94 | if (ret < 0) { |
95 | dev_err(&client->dev, |
96 | "i2c read fail: can't read from %02x: %d\n" , |
97 | reg, ret); |
98 | return ret; |
99 | } |
100 | *val = ret; |
101 | return 0; |
102 | } |
103 | |
104 | static int max14656_write_reg(struct i2c_client *client, int reg, u8 val) |
105 | { |
106 | s32 ret; |
107 | |
108 | ret = i2c_smbus_write_byte_data(client, command: reg, value: val); |
109 | if (ret < 0) { |
110 | dev_err(&client->dev, |
111 | "i2c write fail: can't write %02x to %02x: %d\n" , |
112 | val, reg, ret); |
113 | return ret; |
114 | } |
115 | return 0; |
116 | } |
117 | |
118 | static int max14656_read_block_reg(struct i2c_client *client, u8 reg, |
119 | u8 length, u8 *val) |
120 | { |
121 | int ret; |
122 | |
123 | ret = i2c_smbus_read_i2c_block_data(client, command: reg, length, values: val); |
124 | if (ret < 0) { |
125 | dev_err(&client->dev, "failed to block read reg 0x%x: %d\n" , |
126 | reg, ret); |
127 | return ret; |
128 | } |
129 | |
130 | return 0; |
131 | } |
132 | |
133 | #define REG_TOTAL_NUM 5 |
134 | static void max14656_irq_worker(struct work_struct *work) |
135 | { |
136 | struct max14656_chip *chip = |
137 | container_of(work, struct max14656_chip, irq_work.work); |
138 | |
139 | u8 buf[REG_TOTAL_NUM]; |
140 | u8 chg_type; |
141 | |
142 | max14656_read_block_reg(client: chip->client, MAX14656_DEVICE_ID, |
143 | REG_TOTAL_NUM, val: buf); |
144 | |
145 | if ((buf[MAX14656_STATUS_1] & STATUS1_VB_VALID_MASK) && |
146 | (buf[MAX14656_STATUS_1] & STATUS1_CHG_TYPE_MASK)) { |
147 | chg_type = buf[MAX14656_STATUS_1] & STATUS1_CHG_TYPE_MASK; |
148 | if (chg_type < MAX14656_CHARGER_LAST) |
149 | chip->psy_desc.type = chg_type_props[chg_type].type; |
150 | else |
151 | chip->psy_desc.type = POWER_SUPPLY_TYPE_UNKNOWN; |
152 | chip->online = 1; |
153 | } else { |
154 | chip->online = 0; |
155 | chip->psy_desc.type = POWER_SUPPLY_TYPE_UNKNOWN; |
156 | } |
157 | |
158 | power_supply_changed(psy: chip->detect_psy); |
159 | } |
160 | |
161 | static irqreturn_t max14656_irq(int irq, void *dev_id) |
162 | { |
163 | struct max14656_chip *chip = dev_id; |
164 | |
165 | schedule_delayed_work(dwork: &chip->irq_work, delay: msecs_to_jiffies(m: 100)); |
166 | |
167 | return IRQ_HANDLED; |
168 | } |
169 | |
170 | static int max14656_hw_init(struct max14656_chip *chip) |
171 | { |
172 | uint8_t val = 0; |
173 | uint8_t rev; |
174 | struct i2c_client *client = chip->client; |
175 | |
176 | if (max14656_read_reg(client, MAX14656_DEVICE_ID, val: &val)) |
177 | return -ENODEV; |
178 | |
179 | if ((val & DEVICE_VENDOR_MASK) != 0x20) { |
180 | dev_err(&client->dev, "wrong vendor ID %d\n" , |
181 | ((val & DEVICE_VENDOR_MASK) >> 4)); |
182 | return -ENODEV; |
183 | } |
184 | rev = val & DEVICE_REV_MASK; |
185 | |
186 | /* Turn on ADC_EN */ |
187 | if (max14656_write_reg(client, MAX14656_CONTROL_2, CONTROL2_ADC_EN)) |
188 | return -EINVAL; |
189 | |
190 | /* turn on interrupts and low power mode */ |
191 | if (max14656_write_reg(client, MAX14656_CONTROL_1, |
192 | CONTROL1_DEFAULT | |
193 | CONTROL1_INT_EN | |
194 | CONTROL1_INT_ACTIVE_HIGH | |
195 | CONTROL1_EDGE)) |
196 | return -EINVAL; |
197 | |
198 | if (max14656_write_reg(client, MAX14656_INTMASK_1, val: 0x3)) |
199 | return -EINVAL; |
200 | |
201 | if (max14656_write_reg(client, MAX14656_INTMASK_2, val: 0x1)) |
202 | return -EINVAL; |
203 | |
204 | dev_info(&client->dev, "detected revision %d\n" , rev); |
205 | return 0; |
206 | } |
207 | |
208 | static int max14656_get_property(struct power_supply *psy, |
209 | enum power_supply_property psp, |
210 | union power_supply_propval *val) |
211 | { |
212 | struct max14656_chip *chip = power_supply_get_drvdata(psy); |
213 | |
214 | switch (psp) { |
215 | case POWER_SUPPLY_PROP_ONLINE: |
216 | val->intval = chip->online; |
217 | break; |
218 | case POWER_SUPPLY_PROP_MODEL_NAME: |
219 | val->strval = MAX14656_NAME; |
220 | break; |
221 | case POWER_SUPPLY_PROP_MANUFACTURER: |
222 | val->strval = MAX14656_MANUFACTURER; |
223 | break; |
224 | default: |
225 | return -EINVAL; |
226 | } |
227 | |
228 | return 0; |
229 | } |
230 | |
231 | static enum power_supply_property max14656_battery_props[] = { |
232 | POWER_SUPPLY_PROP_ONLINE, |
233 | POWER_SUPPLY_PROP_MODEL_NAME, |
234 | POWER_SUPPLY_PROP_MANUFACTURER, |
235 | }; |
236 | |
237 | static int max14656_probe(struct i2c_client *client) |
238 | { |
239 | struct i2c_adapter *adapter = client->adapter; |
240 | struct device *dev = &client->dev; |
241 | struct power_supply_config psy_cfg = {}; |
242 | struct max14656_chip *chip; |
243 | int irq = client->irq; |
244 | int ret = 0; |
245 | |
246 | if (irq <= 0) { |
247 | dev_err(dev, "invalid irq number: %d\n" , irq); |
248 | return -ENODEV; |
249 | } |
250 | |
251 | if (!i2c_check_functionality(adap: adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { |
252 | dev_err(dev, "No support for SMBUS_BYTE_DATA\n" ); |
253 | return -ENODEV; |
254 | } |
255 | |
256 | chip = devm_kzalloc(dev, size: sizeof(*chip), GFP_KERNEL); |
257 | if (!chip) |
258 | return -ENOMEM; |
259 | |
260 | psy_cfg.drv_data = chip; |
261 | chip->client = client; |
262 | chip->online = 0; |
263 | chip->psy_desc.name = MAX14656_NAME; |
264 | chip->psy_desc.type = POWER_SUPPLY_TYPE_UNKNOWN; |
265 | chip->psy_desc.properties = max14656_battery_props; |
266 | chip->psy_desc.num_properties = ARRAY_SIZE(max14656_battery_props); |
267 | chip->psy_desc.get_property = max14656_get_property; |
268 | chip->irq = irq; |
269 | |
270 | ret = max14656_hw_init(chip); |
271 | if (ret) |
272 | return -ENODEV; |
273 | |
274 | chip->detect_psy = devm_power_supply_register(parent: dev, |
275 | desc: &chip->psy_desc, cfg: &psy_cfg); |
276 | if (IS_ERR(ptr: chip->detect_psy)) { |
277 | dev_err(dev, "power_supply_register failed\n" ); |
278 | return -EINVAL; |
279 | } |
280 | |
281 | ret = devm_delayed_work_autocancel(dev, w: &chip->irq_work, |
282 | worker: max14656_irq_worker); |
283 | if (ret) { |
284 | dev_err(dev, "devm_delayed_work_autocancel %d failed\n" , ret); |
285 | return ret; |
286 | } |
287 | |
288 | ret = devm_request_irq(dev, irq: chip->irq, handler: max14656_irq, |
289 | IRQF_TRIGGER_FALLING, |
290 | MAX14656_NAME, dev_id: chip); |
291 | if (ret) { |
292 | dev_err(dev, "request_irq %d failed\n" , chip->irq); |
293 | return -EINVAL; |
294 | } |
295 | enable_irq_wake(irq: chip->irq); |
296 | |
297 | schedule_delayed_work(dwork: &chip->irq_work, delay: msecs_to_jiffies(m: 2000)); |
298 | |
299 | return 0; |
300 | } |
301 | |
302 | static const struct i2c_device_id max14656_id[] = { |
303 | { "max14656" , 0 }, |
304 | {} |
305 | }; |
306 | MODULE_DEVICE_TABLE(i2c, max14656_id); |
307 | |
308 | static const struct of_device_id max14656_match_table[] = { |
309 | { .compatible = "maxim,max14656" , }, |
310 | {} |
311 | }; |
312 | MODULE_DEVICE_TABLE(of, max14656_match_table); |
313 | |
314 | static struct i2c_driver max14656_i2c_driver = { |
315 | .driver = { |
316 | .name = "max14656" , |
317 | .of_match_table = max14656_match_table, |
318 | }, |
319 | .probe = max14656_probe, |
320 | .id_table = max14656_id, |
321 | }; |
322 | module_i2c_driver(max14656_i2c_driver); |
323 | |
324 | MODULE_DESCRIPTION("MAX14656 USB charger detector" ); |
325 | MODULE_LICENSE("GPL v2" ); |
326 | |