1 | // SPDX-License-Identifier: GPL-2.0-or-later |
2 | /* |
3 | * twl_core.c - driver for TWL4030/TWL5030/TWL60X0/TPS659x0 PM |
4 | * and audio CODEC devices |
5 | * |
6 | * Copyright (C) 2005-2006 Texas Instruments, Inc. |
7 | * |
8 | * Modifications to defer interrupt handling to a kernel thread: |
9 | * Copyright (C) 2006 MontaVista Software, Inc. |
10 | * |
11 | * Based on tlv320aic23.c: |
12 | * Copyright (c) by Kai Svahn <kai.svahn@nokia.com> |
13 | * |
14 | * Code cleanup and modifications to IRQ handler. |
15 | * by syed khasim <x0khasim@ti.com> |
16 | */ |
17 | |
18 | #include <linux/init.h> |
19 | #include <linux/mutex.h> |
20 | #include <linux/platform_device.h> |
21 | #include <linux/regmap.h> |
22 | #include <linux/clk.h> |
23 | #include <linux/err.h> |
24 | #include <linux/device.h> |
25 | #include <linux/of.h> |
26 | #include <linux/of_irq.h> |
27 | #include <linux/of_platform.h> |
28 | #include <linux/irq.h> |
29 | #include <linux/irqdomain.h> |
30 | |
31 | #include <linux/regulator/machine.h> |
32 | |
33 | #include <linux/i2c.h> |
34 | |
35 | #include <linux/mfd/core.h> |
36 | #include <linux/mfd/twl.h> |
37 | |
38 | /* Register descriptions for audio */ |
39 | #include <linux/mfd/twl4030-audio.h> |
40 | |
41 | #include "twl-core.h" |
42 | |
43 | /* |
44 | * The TWL4030 "Triton 2" is one of a family of a multi-function "Power |
45 | * Management and System Companion Device" chips originally designed for |
46 | * use in OMAP2 and OMAP 3 based systems. Its control interfaces use I2C, |
47 | * often at around 3 Mbit/sec, including for interrupt handling. |
48 | * |
49 | * This driver core provides genirq support for the interrupts emitted, |
50 | * by the various modules, and exports register access primitives. |
51 | * |
52 | * FIXME this driver currently requires use of the first interrupt line |
53 | * (and associated registers). |
54 | */ |
55 | |
56 | #define DRIVER_NAME "twl" |
57 | |
58 | /* Triton Core internal information (BEGIN) */ |
59 | |
60 | /* Base Address defns for twl4030_map[] */ |
61 | |
62 | /* subchip/slave 0 - USB ID */ |
63 | #define TWL4030_BASEADD_USB 0x0000 |
64 | |
65 | /* subchip/slave 1 - AUD ID */ |
66 | #define TWL4030_BASEADD_AUDIO_VOICE 0x0000 |
67 | #define TWL4030_BASEADD_GPIO 0x0098 |
68 | #define TWL4030_BASEADD_INTBR 0x0085 |
69 | #define TWL4030_BASEADD_PIH 0x0080 |
70 | #define TWL4030_BASEADD_TEST 0x004C |
71 | |
72 | /* subchip/slave 2 - AUX ID */ |
73 | #define TWL4030_BASEADD_INTERRUPTS 0x00B9 |
74 | #define TWL4030_BASEADD_LED 0x00EE |
75 | #define TWL4030_BASEADD_MADC 0x0000 |
76 | #define TWL4030_BASEADD_MAIN_CHARGE 0x0074 |
77 | #define TWL4030_BASEADD_PRECHARGE 0x00AA |
78 | #define TWL4030_BASEADD_PWM 0x00F8 |
79 | #define TWL4030_BASEADD_KEYPAD 0x00D2 |
80 | |
81 | #define TWL5031_BASEADD_ACCESSORY 0x0074 /* Replaces Main Charge */ |
82 | #define TWL5031_BASEADD_INTERRUPTS 0x00B9 /* Different than TWL4030's |
83 | one */ |
84 | |
85 | /* subchip/slave 3 - POWER ID */ |
86 | #define TWL4030_BASEADD_BACKUP 0x0014 |
87 | #define TWL4030_BASEADD_INT 0x002E |
88 | #define TWL4030_BASEADD_PM_MASTER 0x0036 |
89 | |
90 | #define TWL4030_BASEADD_PM_RECEIVER 0x005B |
91 | #define TWL4030_DCDC_GLOBAL_CFG 0x06 |
92 | #define SMARTREFLEX_ENABLE BIT(3) |
93 | |
94 | #define TWL4030_BASEADD_RTC 0x001C |
95 | #define TWL4030_BASEADD_SECURED_REG 0x0000 |
96 | |
97 | /* Triton Core internal information (END) */ |
98 | |
99 | |
100 | /* subchip/slave 0 0x48 - POWER */ |
101 | #define TWL6030_BASEADD_RTC 0x0000 |
102 | #define TWL6030_BASEADD_SECURED_REG 0x0017 |
103 | #define TWL6030_BASEADD_PM_MASTER 0x001F |
104 | #define TWL6030_BASEADD_PM_SLAVE_MISC 0x0030 /* PM_RECEIVER */ |
105 | #define TWL6030_BASEADD_PM_MISC 0x00E2 |
106 | #define TWL6030_BASEADD_PM_PUPD 0x00F0 |
107 | |
108 | /* subchip/slave 1 0x49 - FEATURE */ |
109 | #define TWL6030_BASEADD_USB 0x0000 |
110 | #define TWL6030_BASEADD_GPADC_CTRL 0x002E |
111 | #define TWL6030_BASEADD_AUX 0x0090 |
112 | #define TWL6030_BASEADD_PWM 0x00BA |
113 | #define TWL6030_BASEADD_GASGAUGE 0x00C0 |
114 | #define TWL6030_BASEADD_PIH 0x00D0 |
115 | #define TWL6032_BASEADD_CHARGER 0x00DA |
116 | #define TWL6030_BASEADD_CHARGER 0x00E0 |
117 | #define TWL6030_BASEADD_LED 0x00F4 |
118 | |
119 | /* subchip/slave 2 0x4A - DFT */ |
120 | #define TWL6030_BASEADD_DIEID 0x00C0 |
121 | |
122 | /* subchip/slave 3 0x4B - AUDIO */ |
123 | #define TWL6030_BASEADD_AUDIO 0x0000 |
124 | #define TWL6030_BASEADD_RSV 0x0000 |
125 | #define TWL6030_BASEADD_ZERO 0x0000 |
126 | |
127 | /* Few power values */ |
128 | #define R_CFG_BOOT 0x05 |
129 | |
130 | /* some fields in R_CFG_BOOT */ |
131 | #define HFCLK_FREQ_19p2_MHZ (1 << 0) |
132 | #define HFCLK_FREQ_26_MHZ (2 << 0) |
133 | #define HFCLK_FREQ_38p4_MHZ (3 << 0) |
134 | #define HIGH_PERF_SQ (1 << 3) |
135 | #define CK32K_LOWPWR_EN (1 << 7) |
136 | |
137 | /*----------------------------------------------------------------------*/ |
138 | |
139 | /* Structure for each TWL4030/TWL6030 Slave */ |
140 | struct twl_client { |
141 | struct i2c_client *client; |
142 | struct regmap *regmap; |
143 | }; |
144 | |
145 | /* mapping the module id to slave id and base address */ |
146 | struct twl_mapping { |
147 | unsigned char sid; /* Slave ID */ |
148 | unsigned char base; /* base address */ |
149 | }; |
150 | |
151 | struct twl_private { |
152 | bool ready; /* The core driver is ready to be used */ |
153 | u32 twl_idcode; /* TWL IDCODE Register value */ |
154 | unsigned int twl_id; |
155 | |
156 | struct twl_mapping *twl_map; |
157 | struct twl_client *twl_modules; |
158 | }; |
159 | |
160 | static struct twl_private *twl_priv; |
161 | |
162 | static struct twl_mapping twl4030_map[] = { |
163 | /* |
164 | * NOTE: don't change this table without updating the |
165 | * <linux/mfd/twl.h> defines for TWL4030_MODULE_* |
166 | * so they continue to match the order in this table. |
167 | */ |
168 | |
169 | /* Common IPs */ |
170 | { 0, TWL4030_BASEADD_USB }, |
171 | { 1, TWL4030_BASEADD_PIH }, |
172 | { 2, TWL4030_BASEADD_MAIN_CHARGE }, |
173 | { 3, TWL4030_BASEADD_PM_MASTER }, |
174 | { 3, TWL4030_BASEADD_PM_RECEIVER }, |
175 | |
176 | { 3, TWL4030_BASEADD_RTC }, |
177 | { 2, TWL4030_BASEADD_PWM }, |
178 | { 2, TWL4030_BASEADD_LED }, |
179 | { 3, TWL4030_BASEADD_SECURED_REG }, |
180 | |
181 | /* TWL4030 specific IPs */ |
182 | { 1, TWL4030_BASEADD_AUDIO_VOICE }, |
183 | { 1, TWL4030_BASEADD_GPIO }, |
184 | { 1, TWL4030_BASEADD_INTBR }, |
185 | { 1, TWL4030_BASEADD_TEST }, |
186 | { 2, TWL4030_BASEADD_KEYPAD }, |
187 | |
188 | { 2, TWL4030_BASEADD_MADC }, |
189 | { 2, TWL4030_BASEADD_INTERRUPTS }, |
190 | { 2, TWL4030_BASEADD_PRECHARGE }, |
191 | { 3, TWL4030_BASEADD_BACKUP }, |
192 | { 3, TWL4030_BASEADD_INT }, |
193 | |
194 | { 2, TWL5031_BASEADD_ACCESSORY }, |
195 | { 2, TWL5031_BASEADD_INTERRUPTS }, |
196 | }; |
197 | |
198 | static const struct reg_default twl4030_49_defaults[] = { |
199 | /* Audio Registers */ |
200 | { 0x01, 0x00}, /* CODEC_MODE */ |
201 | { 0x02, 0x00}, /* OPTION */ |
202 | /* 0x03 Unused */ |
203 | { 0x04, 0x00}, /* MICBIAS_CTL */ |
204 | { 0x05, 0x00}, /* ANAMICL */ |
205 | { 0x06, 0x00}, /* ANAMICR */ |
206 | { 0x07, 0x00}, /* AVADC_CTL */ |
207 | { 0x08, 0x00}, /* ADCMICSEL */ |
208 | { 0x09, 0x00}, /* DIGMIXING */ |
209 | { 0x0a, 0x0f}, /* ATXL1PGA */ |
210 | { 0x0b, 0x0f}, /* ATXR1PGA */ |
211 | { 0x0c, 0x0f}, /* AVTXL2PGA */ |
212 | { 0x0d, 0x0f}, /* AVTXR2PGA */ |
213 | { 0x0e, 0x00}, /* AUDIO_IF */ |
214 | { 0x0f, 0x00}, /* VOICE_IF */ |
215 | { 0x10, 0x3f}, /* ARXR1PGA */ |
216 | { 0x11, 0x3f}, /* ARXL1PGA */ |
217 | { 0x12, 0x3f}, /* ARXR2PGA */ |
218 | { 0x13, 0x3f}, /* ARXL2PGA */ |
219 | { 0x14, 0x25}, /* VRXPGA */ |
220 | { 0x15, 0x00}, /* VSTPGA */ |
221 | { 0x16, 0x00}, /* VRX2ARXPGA */ |
222 | { 0x17, 0x00}, /* AVDAC_CTL */ |
223 | { 0x18, 0x00}, /* ARX2VTXPGA */ |
224 | { 0x19, 0x32}, /* ARXL1_APGA_CTL*/ |
225 | { 0x1a, 0x32}, /* ARXR1_APGA_CTL*/ |
226 | { 0x1b, 0x32}, /* ARXL2_APGA_CTL*/ |
227 | { 0x1c, 0x32}, /* ARXR2_APGA_CTL*/ |
228 | { 0x1d, 0x00}, /* ATX2ARXPGA */ |
229 | { 0x1e, 0x00}, /* BT_IF */ |
230 | { 0x1f, 0x55}, /* BTPGA */ |
231 | { 0x20, 0x00}, /* BTSTPGA */ |
232 | { 0x21, 0x00}, /* EAR_CTL */ |
233 | { 0x22, 0x00}, /* HS_SEL */ |
234 | { 0x23, 0x00}, /* HS_GAIN_SET */ |
235 | { 0x24, 0x00}, /* HS_POPN_SET */ |
236 | { 0x25, 0x00}, /* PREDL_CTL */ |
237 | { 0x26, 0x00}, /* PREDR_CTL */ |
238 | { 0x27, 0x00}, /* PRECKL_CTL */ |
239 | { 0x28, 0x00}, /* PRECKR_CTL */ |
240 | { 0x29, 0x00}, /* HFL_CTL */ |
241 | { 0x2a, 0x00}, /* HFR_CTL */ |
242 | { 0x2b, 0x05}, /* ALC_CTL */ |
243 | { 0x2c, 0x00}, /* ALC_SET1 */ |
244 | { 0x2d, 0x00}, /* ALC_SET2 */ |
245 | { 0x2e, 0x00}, /* BOOST_CTL */ |
246 | { 0x2f, 0x00}, /* SOFTVOL_CTL */ |
247 | { 0x30, 0x13}, /* DTMF_FREQSEL */ |
248 | { 0x31, 0x00}, /* DTMF_TONEXT1H */ |
249 | { 0x32, 0x00}, /* DTMF_TONEXT1L */ |
250 | { 0x33, 0x00}, /* DTMF_TONEXT2H */ |
251 | { 0x34, 0x00}, /* DTMF_TONEXT2L */ |
252 | { 0x35, 0x79}, /* DTMF_TONOFF */ |
253 | { 0x36, 0x11}, /* DTMF_WANONOFF */ |
254 | { 0x37, 0x00}, /* I2S_RX_SCRAMBLE_H */ |
255 | { 0x38, 0x00}, /* I2S_RX_SCRAMBLE_M */ |
256 | { 0x39, 0x00}, /* I2S_RX_SCRAMBLE_L */ |
257 | { 0x3a, 0x06}, /* APLL_CTL */ |
258 | { 0x3b, 0x00}, /* DTMF_CTL */ |
259 | { 0x3c, 0x44}, /* DTMF_PGA_CTL2 (0x3C) */ |
260 | { 0x3d, 0x69}, /* DTMF_PGA_CTL1 (0x3D) */ |
261 | { 0x3e, 0x00}, /* MISC_SET_1 */ |
262 | { 0x3f, 0x00}, /* PCMBTMUX */ |
263 | /* 0x40 - 0x42 Unused */ |
264 | { 0x43, 0x00}, /* RX_PATH_SEL */ |
265 | { 0x44, 0x32}, /* VDL_APGA_CTL */ |
266 | { 0x45, 0x00}, /* VIBRA_CTL */ |
267 | { 0x46, 0x00}, /* VIBRA_SET */ |
268 | { 0x47, 0x00}, /* VIBRA_PWM_SET */ |
269 | { 0x48, 0x00}, /* ANAMIC_GAIN */ |
270 | { 0x49, 0x00}, /* MISC_SET_2 */ |
271 | /* End of Audio Registers */ |
272 | }; |
273 | |
274 | static bool twl4030_49_nop_reg(struct device *dev, unsigned int reg) |
275 | { |
276 | switch (reg) { |
277 | case 0x00: |
278 | case 0x03: |
279 | case 0x40: |
280 | case 0x41: |
281 | case 0x42: |
282 | return false; |
283 | default: |
284 | return true; |
285 | } |
286 | } |
287 | |
288 | static const struct regmap_range twl4030_49_volatile_ranges[] = { |
289 | regmap_reg_range(TWL4030_BASEADD_TEST, 0xff), |
290 | }; |
291 | |
292 | static const struct regmap_access_table twl4030_49_volatile_table = { |
293 | .yes_ranges = twl4030_49_volatile_ranges, |
294 | .n_yes_ranges = ARRAY_SIZE(twl4030_49_volatile_ranges), |
295 | }; |
296 | |
297 | static const struct regmap_config twl4030_regmap_config[4] = { |
298 | { |
299 | /* Address 0x48 */ |
300 | .reg_bits = 8, |
301 | .val_bits = 8, |
302 | .max_register = 0xff, |
303 | }, |
304 | { |
305 | /* Address 0x49 */ |
306 | .reg_bits = 8, |
307 | .val_bits = 8, |
308 | .max_register = 0xff, |
309 | |
310 | .readable_reg = twl4030_49_nop_reg, |
311 | .writeable_reg = twl4030_49_nop_reg, |
312 | |
313 | .volatile_table = &twl4030_49_volatile_table, |
314 | |
315 | .reg_defaults = twl4030_49_defaults, |
316 | .num_reg_defaults = ARRAY_SIZE(twl4030_49_defaults), |
317 | .cache_type = REGCACHE_MAPLE, |
318 | }, |
319 | { |
320 | /* Address 0x4a */ |
321 | .reg_bits = 8, |
322 | .val_bits = 8, |
323 | .max_register = 0xff, |
324 | }, |
325 | { |
326 | /* Address 0x4b */ |
327 | .reg_bits = 8, |
328 | .val_bits = 8, |
329 | .max_register = 0xff, |
330 | }, |
331 | }; |
332 | |
333 | static struct twl_mapping twl6030_map[] = { |
334 | /* |
335 | * NOTE: don't change this table without updating the |
336 | * <linux/mfd/twl.h> defines for TWL4030_MODULE_* |
337 | * so they continue to match the order in this table. |
338 | */ |
339 | |
340 | /* Common IPs */ |
341 | { 1, TWL6030_BASEADD_USB }, |
342 | { 1, TWL6030_BASEADD_PIH }, |
343 | { 1, TWL6030_BASEADD_CHARGER }, |
344 | { 0, TWL6030_BASEADD_PM_MASTER }, |
345 | { 0, TWL6030_BASEADD_PM_SLAVE_MISC }, |
346 | |
347 | { 0, TWL6030_BASEADD_RTC }, |
348 | { 1, TWL6030_BASEADD_PWM }, |
349 | { 1, TWL6030_BASEADD_LED }, |
350 | { 0, TWL6030_BASEADD_SECURED_REG }, |
351 | |
352 | /* TWL6030 specific IPs */ |
353 | { 0, TWL6030_BASEADD_ZERO }, |
354 | { 1, TWL6030_BASEADD_ZERO }, |
355 | { 2, TWL6030_BASEADD_ZERO }, |
356 | { 1, TWL6030_BASEADD_GPADC_CTRL }, |
357 | { 1, TWL6030_BASEADD_GASGAUGE }, |
358 | |
359 | /* TWL6032 specific charger registers */ |
360 | { 1, TWL6032_BASEADD_CHARGER }, |
361 | }; |
362 | |
363 | static const struct regmap_config twl6030_regmap_config[3] = { |
364 | { |
365 | /* Address 0x48 */ |
366 | .reg_bits = 8, |
367 | .val_bits = 8, |
368 | .max_register = 0xff, |
369 | }, |
370 | { |
371 | /* Address 0x49 */ |
372 | .reg_bits = 8, |
373 | .val_bits = 8, |
374 | .max_register = 0xff, |
375 | }, |
376 | { |
377 | /* Address 0x4a */ |
378 | .reg_bits = 8, |
379 | .val_bits = 8, |
380 | .max_register = 0xff, |
381 | }, |
382 | }; |
383 | |
384 | /*----------------------------------------------------------------------*/ |
385 | |
386 | static inline int twl_get_num_slaves(void) |
387 | { |
388 | if (twl_class_is_4030()) |
389 | return 4; /* TWL4030 class have four slave address */ |
390 | else |
391 | return 3; /* TWL6030 class have three slave address */ |
392 | } |
393 | |
394 | static inline int twl_get_last_module(void) |
395 | { |
396 | if (twl_class_is_4030()) |
397 | return TWL4030_MODULE_LAST; |
398 | else |
399 | return TWL6030_MODULE_LAST; |
400 | } |
401 | |
402 | /* Exported Functions */ |
403 | |
404 | unsigned int twl_rev(void) |
405 | { |
406 | return twl_priv ? twl_priv->twl_id : 0; |
407 | } |
408 | EXPORT_SYMBOL(twl_rev); |
409 | |
410 | /** |
411 | * twl_get_regmap - Get the regmap associated with the given module |
412 | * @mod_no: module number |
413 | * |
414 | * Returns the regmap pointer or NULL in case of failure. |
415 | */ |
416 | static struct regmap *twl_get_regmap(u8 mod_no) |
417 | { |
418 | int sid; |
419 | struct twl_client *twl; |
420 | |
421 | if (unlikely(!twl_priv || !twl_priv->ready)) { |
422 | pr_err("%s: not initialized\n" , DRIVER_NAME); |
423 | return NULL; |
424 | } |
425 | if (unlikely(mod_no >= twl_get_last_module())) { |
426 | pr_err("%s: invalid module number %d\n" , DRIVER_NAME, mod_no); |
427 | return NULL; |
428 | } |
429 | |
430 | sid = twl_priv->twl_map[mod_no].sid; |
431 | twl = &twl_priv->twl_modules[sid]; |
432 | |
433 | return twl->regmap; |
434 | } |
435 | |
436 | /** |
437 | * twl_i2c_write - Writes a n bit register in TWL4030/TWL5030/TWL60X0 |
438 | * @mod_no: module number |
439 | * @value: an array of num_bytes+1 containing data to write |
440 | * @reg: register address (just offset will do) |
441 | * @num_bytes: number of bytes to transfer |
442 | * |
443 | * Returns 0 on success or else a negative error code. |
444 | */ |
445 | int twl_i2c_write(u8 mod_no, u8 *value, u8 reg, unsigned num_bytes) |
446 | { |
447 | struct regmap *regmap = twl_get_regmap(mod_no); |
448 | int ret; |
449 | |
450 | if (!regmap) |
451 | return -EPERM; |
452 | |
453 | ret = regmap_bulk_write(map: regmap, reg: twl_priv->twl_map[mod_no].base + reg, |
454 | val: value, val_count: num_bytes); |
455 | |
456 | if (ret) |
457 | pr_err("%s: Write failed (mod %d, reg 0x%02x count %d)\n" , |
458 | DRIVER_NAME, mod_no, reg, num_bytes); |
459 | |
460 | return ret; |
461 | } |
462 | EXPORT_SYMBOL(twl_i2c_write); |
463 | |
464 | /** |
465 | * twl_i2c_read - Reads a n bit register in TWL4030/TWL5030/TWL60X0 |
466 | * @mod_no: module number |
467 | * @value: an array of num_bytes containing data to be read |
468 | * @reg: register address (just offset will do) |
469 | * @num_bytes: number of bytes to transfer |
470 | * |
471 | * Returns 0 on success or else a negative error code. |
472 | */ |
473 | int twl_i2c_read(u8 mod_no, u8 *value, u8 reg, unsigned num_bytes) |
474 | { |
475 | struct regmap *regmap = twl_get_regmap(mod_no); |
476 | int ret; |
477 | |
478 | if (!regmap) |
479 | return -EPERM; |
480 | |
481 | ret = regmap_bulk_read(map: regmap, reg: twl_priv->twl_map[mod_no].base + reg, |
482 | val: value, val_count: num_bytes); |
483 | |
484 | if (ret) |
485 | pr_err("%s: Read failed (mod %d, reg 0x%02x count %d)\n" , |
486 | DRIVER_NAME, mod_no, reg, num_bytes); |
487 | |
488 | return ret; |
489 | } |
490 | EXPORT_SYMBOL(twl_i2c_read); |
491 | |
492 | /** |
493 | * twl_set_regcache_bypass - Configure the regcache bypass for the regmap associated |
494 | * with the module |
495 | * @mod_no: module number |
496 | * @enable: Regcache bypass state |
497 | * |
498 | * Returns 0 else failure. |
499 | */ |
500 | int twl_set_regcache_bypass(u8 mod_no, bool enable) |
501 | { |
502 | struct regmap *regmap = twl_get_regmap(mod_no); |
503 | |
504 | if (!regmap) |
505 | return -EPERM; |
506 | |
507 | regcache_cache_bypass(map: regmap, enable); |
508 | |
509 | return 0; |
510 | } |
511 | EXPORT_SYMBOL(twl_set_regcache_bypass); |
512 | |
513 | /*----------------------------------------------------------------------*/ |
514 | |
515 | /** |
516 | * twl_read_idcode_register - API to read the IDCODE register. |
517 | * |
518 | * Unlocks the IDCODE register and read the 32 bit value. |
519 | */ |
520 | static int twl_read_idcode_register(void) |
521 | { |
522 | int err; |
523 | |
524 | err = twl_i2c_write_u8(mod_no: TWL4030_MODULE_INTBR, TWL_EEPROM_R_UNLOCK, |
525 | REG_UNLOCK_TEST_REG); |
526 | if (err) { |
527 | pr_err("TWL4030 Unable to unlock IDCODE registers -%d\n" , err); |
528 | goto fail; |
529 | } |
530 | |
531 | err = twl_i2c_read(TWL4030_MODULE_INTBR, (u8 *)(&twl_priv->twl_idcode), |
532 | REG_IDCODE_7_0, 4); |
533 | if (err) { |
534 | pr_err("TWL4030: unable to read IDCODE -%d\n" , err); |
535 | goto fail; |
536 | } |
537 | |
538 | err = twl_i2c_write_u8(mod_no: TWL4030_MODULE_INTBR, val: 0x0, REG_UNLOCK_TEST_REG); |
539 | if (err) |
540 | pr_err("TWL4030 Unable to relock IDCODE registers -%d\n" , err); |
541 | fail: |
542 | return err; |
543 | } |
544 | |
545 | /** |
546 | * twl_get_type - API to get TWL Si type. |
547 | * |
548 | * Api to get the TWL Si type from IDCODE value. |
549 | */ |
550 | int twl_get_type(void) |
551 | { |
552 | return TWL_SIL_TYPE(twl_priv->twl_idcode); |
553 | } |
554 | EXPORT_SYMBOL_GPL(twl_get_type); |
555 | |
556 | /** |
557 | * twl_get_version - API to get TWL Si version. |
558 | * |
559 | * Api to get the TWL Si version from IDCODE value. |
560 | */ |
561 | int twl_get_version(void) |
562 | { |
563 | return TWL_SIL_REV(twl_priv->twl_idcode); |
564 | } |
565 | EXPORT_SYMBOL_GPL(twl_get_version); |
566 | |
567 | /** |
568 | * twl_get_hfclk_rate - API to get TWL external HFCLK clock rate. |
569 | * |
570 | * Api to get the TWL HFCLK rate based on BOOT_CFG register. |
571 | */ |
572 | int twl_get_hfclk_rate(void) |
573 | { |
574 | u8 ctrl; |
575 | int rate; |
576 | |
577 | twl_i2c_read_u8(mod_no: TWL_MODULE_PM_MASTER, val: &ctrl, R_CFG_BOOT); |
578 | |
579 | switch (ctrl & 0x3) { |
580 | case HFCLK_FREQ_19p2_MHZ: |
581 | rate = 19200000; |
582 | break; |
583 | case HFCLK_FREQ_26_MHZ: |
584 | rate = 26000000; |
585 | break; |
586 | case HFCLK_FREQ_38p4_MHZ: |
587 | rate = 38400000; |
588 | break; |
589 | default: |
590 | pr_err("TWL4030: HFCLK is not configured\n" ); |
591 | rate = -EINVAL; |
592 | break; |
593 | } |
594 | |
595 | return rate; |
596 | } |
597 | EXPORT_SYMBOL_GPL(twl_get_hfclk_rate); |
598 | |
599 | /*----------------------------------------------------------------------*/ |
600 | |
601 | /* |
602 | * These three functions initialize the on-chip clock framework, |
603 | * letting it generate the right frequencies for USB, MADC, and |
604 | * other purposes. |
605 | */ |
606 | static inline int protect_pm_master(void) |
607 | { |
608 | int e = 0; |
609 | |
610 | e = twl_i2c_write_u8(mod_no: TWL_MODULE_PM_MASTER, val: 0, |
611 | TWL4030_PM_MASTER_PROTECT_KEY); |
612 | return e; |
613 | } |
614 | |
615 | static inline int unprotect_pm_master(void) |
616 | { |
617 | int e = 0; |
618 | |
619 | e |= twl_i2c_write_u8(mod_no: TWL_MODULE_PM_MASTER, TWL4030_PM_MASTER_KEY_CFG1, |
620 | TWL4030_PM_MASTER_PROTECT_KEY); |
621 | e |= twl_i2c_write_u8(mod_no: TWL_MODULE_PM_MASTER, TWL4030_PM_MASTER_KEY_CFG2, |
622 | TWL4030_PM_MASTER_PROTECT_KEY); |
623 | |
624 | return e; |
625 | } |
626 | |
627 | static void clocks_init(struct device *dev) |
628 | { |
629 | int e = 0; |
630 | struct clk *osc; |
631 | u32 rate; |
632 | u8 ctrl = HFCLK_FREQ_26_MHZ; |
633 | |
634 | osc = clk_get(dev, id: "fck" ); |
635 | if (IS_ERR(ptr: osc)) { |
636 | printk(KERN_WARNING "Skipping twl internal clock init and " |
637 | "using bootloader value (unknown osc rate)\n" ); |
638 | return; |
639 | } |
640 | |
641 | rate = clk_get_rate(clk: osc); |
642 | clk_put(clk: osc); |
643 | |
644 | switch (rate) { |
645 | case 19200000: |
646 | ctrl = HFCLK_FREQ_19p2_MHZ; |
647 | break; |
648 | case 26000000: |
649 | ctrl = HFCLK_FREQ_26_MHZ; |
650 | break; |
651 | case 38400000: |
652 | ctrl = HFCLK_FREQ_38p4_MHZ; |
653 | break; |
654 | } |
655 | |
656 | ctrl |= HIGH_PERF_SQ; |
657 | |
658 | e |= unprotect_pm_master(); |
659 | /* effect->MADC+USB ck en */ |
660 | e |= twl_i2c_write_u8(mod_no: TWL_MODULE_PM_MASTER, val: ctrl, R_CFG_BOOT); |
661 | e |= protect_pm_master(); |
662 | |
663 | if (e < 0) |
664 | pr_err("%s: clock init err [%d]\n" , DRIVER_NAME, e); |
665 | } |
666 | |
667 | /*----------------------------------------------------------------------*/ |
668 | |
669 | |
670 | static void twl_remove(struct i2c_client *client) |
671 | { |
672 | unsigned i, num_slaves; |
673 | |
674 | if (twl_class_is_4030()) |
675 | twl4030_exit_irq(); |
676 | else |
677 | twl6030_exit_irq(); |
678 | |
679 | num_slaves = twl_get_num_slaves(); |
680 | for (i = 0; i < num_slaves; i++) { |
681 | struct twl_client *twl = &twl_priv->twl_modules[i]; |
682 | |
683 | if (twl->client && twl->client != client) |
684 | i2c_unregister_device(client: twl->client); |
685 | twl->client = NULL; |
686 | } |
687 | twl_priv->ready = false; |
688 | } |
689 | |
690 | static struct of_dev_auxdata twl_auxdata_lookup[] = { |
691 | OF_DEV_AUXDATA("ti,twl4030-gpio" , 0, "twl4030-gpio" , NULL), |
692 | { /* sentinel */ }, |
693 | }; |
694 | |
695 | static const struct mfd_cell twl6032_cells[] = { |
696 | { .name = "twl6032-clk" }, |
697 | }; |
698 | |
699 | /* NOTE: This driver only handles a single twl4030/tps659x0 chip */ |
700 | static int |
701 | twl_probe(struct i2c_client *client) |
702 | { |
703 | const struct i2c_device_id *id = i2c_client_get_device_id(client); |
704 | struct device_node *node = client->dev.of_node; |
705 | struct platform_device *pdev; |
706 | const struct regmap_config *twl_regmap_config; |
707 | int irq_base = 0; |
708 | int status; |
709 | unsigned i, num_slaves; |
710 | |
711 | if (!node) { |
712 | dev_err(&client->dev, "no platform data\n" ); |
713 | return -EINVAL; |
714 | } |
715 | |
716 | if (twl_priv) { |
717 | dev_dbg(&client->dev, "only one instance of %s allowed\n" , |
718 | DRIVER_NAME); |
719 | return -EBUSY; |
720 | } |
721 | |
722 | pdev = platform_device_alloc(DRIVER_NAME, id: -1); |
723 | if (!pdev) { |
724 | dev_err(&client->dev, "can't alloc pdev\n" ); |
725 | return -ENOMEM; |
726 | } |
727 | |
728 | status = platform_device_add(pdev); |
729 | if (status) { |
730 | platform_device_put(pdev); |
731 | return status; |
732 | } |
733 | |
734 | if (i2c_check_functionality(adap: client->adapter, I2C_FUNC_I2C) == 0) { |
735 | dev_dbg(&client->dev, "can't talk I2C?\n" ); |
736 | status = -EIO; |
737 | goto free; |
738 | } |
739 | |
740 | twl_priv = devm_kzalloc(dev: &client->dev, size: sizeof(struct twl_private), |
741 | GFP_KERNEL); |
742 | if (!twl_priv) { |
743 | status = -ENOMEM; |
744 | goto free; |
745 | } |
746 | |
747 | if ((id->driver_data) & TWL6030_CLASS) { |
748 | twl_priv->twl_id = TWL6030_CLASS_ID; |
749 | twl_priv->twl_map = &twl6030_map[0]; |
750 | twl_regmap_config = twl6030_regmap_config; |
751 | } else { |
752 | twl_priv->twl_id = TWL4030_CLASS_ID; |
753 | twl_priv->twl_map = &twl4030_map[0]; |
754 | twl_regmap_config = twl4030_regmap_config; |
755 | } |
756 | |
757 | num_slaves = twl_get_num_slaves(); |
758 | twl_priv->twl_modules = devm_kcalloc(dev: &client->dev, |
759 | n: num_slaves, |
760 | size: sizeof(struct twl_client), |
761 | GFP_KERNEL); |
762 | if (!twl_priv->twl_modules) { |
763 | status = -ENOMEM; |
764 | goto free; |
765 | } |
766 | |
767 | for (i = 0; i < num_slaves; i++) { |
768 | struct twl_client *twl = &twl_priv->twl_modules[i]; |
769 | |
770 | if (i == 0) { |
771 | twl->client = client; |
772 | } else { |
773 | twl->client = i2c_new_dummy_device(adapter: client->adapter, |
774 | address: client->addr + i); |
775 | if (IS_ERR(ptr: twl->client)) { |
776 | dev_err(&client->dev, |
777 | "can't attach client %d\n" , i); |
778 | status = PTR_ERR(ptr: twl->client); |
779 | goto fail; |
780 | } |
781 | } |
782 | |
783 | twl->regmap = devm_regmap_init_i2c(twl->client, |
784 | &twl_regmap_config[i]); |
785 | if (IS_ERR(ptr: twl->regmap)) { |
786 | status = PTR_ERR(ptr: twl->regmap); |
787 | dev_err(&client->dev, |
788 | "Failed to allocate regmap %d, err: %d\n" , i, |
789 | status); |
790 | goto fail; |
791 | } |
792 | } |
793 | |
794 | twl_priv->ready = true; |
795 | |
796 | /* setup clock framework */ |
797 | clocks_init(dev: &client->dev); |
798 | |
799 | /* read TWL IDCODE Register */ |
800 | if (twl_class_is_4030()) { |
801 | status = twl_read_idcode_register(); |
802 | WARN(status < 0, "Error: reading twl_idcode register value\n" ); |
803 | } |
804 | |
805 | /* Maybe init the T2 Interrupt subsystem */ |
806 | if (client->irq) { |
807 | if (twl_class_is_4030()) { |
808 | twl4030_init_chip_irq(chip: id->name); |
809 | irq_base = twl4030_init_irq(dev: &client->dev, irq_num: client->irq); |
810 | } else { |
811 | irq_base = twl6030_init_irq(dev: &client->dev, irq_num: client->irq); |
812 | } |
813 | |
814 | if (irq_base < 0) { |
815 | status = irq_base; |
816 | goto fail; |
817 | } |
818 | } |
819 | |
820 | /* |
821 | * Disable TWL4030/TWL5030 I2C Pull-up on I2C1 and I2C4(SR) interface. |
822 | * Program I2C_SCL_CTRL_PU(bit 0)=0, I2C_SDA_CTRL_PU (bit 2)=0, |
823 | * SR_I2C_SCL_CTRL_PU(bit 4)=0 and SR_I2C_SDA_CTRL_PU(bit 6)=0. |
824 | * |
825 | * Also, always enable SmartReflex bit as that's needed for omaps to |
826 | * do anything over I2C4 for voltage scaling even if SmartReflex |
827 | * is disabled. Without the SmartReflex bit omap sys_clkreq idle |
828 | * signal will never trigger for retention idle. |
829 | */ |
830 | if (twl_class_is_4030()) { |
831 | u8 temp; |
832 | |
833 | twl_i2c_read_u8(mod_no: TWL4030_MODULE_INTBR, val: &temp, REG_GPPUPDCTR1); |
834 | temp &= ~(SR_I2C_SDA_CTRL_PU | SR_I2C_SCL_CTRL_PU | \ |
835 | I2C_SDA_CTRL_PU | I2C_SCL_CTRL_PU); |
836 | twl_i2c_write_u8(mod_no: TWL4030_MODULE_INTBR, val: temp, REG_GPPUPDCTR1); |
837 | |
838 | twl_i2c_read_u8(mod_no: TWL_MODULE_PM_RECEIVER, val: &temp, |
839 | TWL4030_DCDC_GLOBAL_CFG); |
840 | temp |= SMARTREFLEX_ENABLE; |
841 | twl_i2c_write_u8(mod_no: TWL_MODULE_PM_RECEIVER, val: temp, |
842 | TWL4030_DCDC_GLOBAL_CFG); |
843 | } |
844 | |
845 | if (id->driver_data == (TWL6030_CLASS | TWL6032_SUBCLASS)) { |
846 | status = devm_mfd_add_devices(dev: &client->dev, |
847 | PLATFORM_DEVID_NONE, |
848 | cells: twl6032_cells, |
849 | ARRAY_SIZE(twl6032_cells), |
850 | NULL, irq_base: 0, NULL); |
851 | if (status < 0) |
852 | goto free; |
853 | } |
854 | |
855 | status = of_platform_populate(root: node, NULL, lookup: twl_auxdata_lookup, |
856 | parent: &client->dev); |
857 | |
858 | fail: |
859 | if (status < 0) |
860 | twl_remove(client); |
861 | free: |
862 | if (status < 0) |
863 | platform_device_unregister(pdev); |
864 | |
865 | return status; |
866 | } |
867 | |
868 | static int __maybe_unused twl_suspend(struct device *dev) |
869 | { |
870 | struct i2c_client *client = to_i2c_client(dev); |
871 | |
872 | if (client->irq) |
873 | disable_irq(irq: client->irq); |
874 | |
875 | return 0; |
876 | } |
877 | |
878 | static int __maybe_unused twl_resume(struct device *dev) |
879 | { |
880 | struct i2c_client *client = to_i2c_client(dev); |
881 | |
882 | if (client->irq) |
883 | enable_irq(irq: client->irq); |
884 | |
885 | return 0; |
886 | } |
887 | |
888 | static SIMPLE_DEV_PM_OPS(twl_dev_pm_ops, twl_suspend, twl_resume); |
889 | |
890 | static const struct i2c_device_id twl_ids[] = { |
891 | { "twl4030" , TWL4030_VAUX2 }, /* "Triton 2" */ |
892 | { "twl5030" , 0 }, /* T2 updated */ |
893 | { "twl5031" , TWL5031 }, /* TWL5030 updated */ |
894 | { "tps65950" , 0 }, /* catalog version of twl5030 */ |
895 | { "tps65930" , TPS_SUBSET }, /* fewer LDOs and DACs; no charger */ |
896 | { "tps65920" , TPS_SUBSET }, /* fewer LDOs; no codec or charger */ |
897 | { "tps65921" , TPS_SUBSET }, /* fewer LDOs; no codec, no LED |
898 | and vibrator. Charger in USB module*/ |
899 | { "twl6030" , TWL6030_CLASS }, /* "Phoenix power chip" */ |
900 | { "twl6032" , TWL6030_CLASS | TWL6032_SUBCLASS }, /* "Phoenix lite" */ |
901 | { /* end of list */ }, |
902 | }; |
903 | |
904 | /* One Client Driver , 4 Clients */ |
905 | static struct i2c_driver twl_driver = { |
906 | .driver.name = DRIVER_NAME, |
907 | .driver.pm = &twl_dev_pm_ops, |
908 | .id_table = twl_ids, |
909 | .probe = twl_probe, |
910 | .remove = twl_remove, |
911 | }; |
912 | builtin_i2c_driver(twl_driver); |
913 | |