4 * Copyright 2011-2012 Texas Instruments Inc.
6 * Author: Graeme Gregory <gg@slimlogic.co.uk>
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
15 #include <linux/module.h>
16 #include <linux/moduleparam.h>
17 #include <linux/init.h>
18 #include <linux/slab.h>
19 #include <linux/i2c.h>
20 #include <linux/interrupt.h>
21 #include <linux/irq.h>
22 #include <linux/regmap.h>
23 #include <linux/err.h>
24 #include <linux/mfd/core.h>
25 #include <linux/mfd/palmas.h>
26 #include <linux/of_platform.h>
42 static struct resource palmas_rtc_resources
[] = {
44 .start
= PALMAS_RTC_ALARM_IRQ
,
45 .end
= PALMAS_RTC_ALARM_IRQ
,
46 .flags
= IORESOURCE_IRQ
,
50 static const struct mfd_cell palmas_children
[] = {
52 .name
= "palmas-pmic",
56 .name
= "palmas-gpio",
60 .name
= "palmas-leds",
70 .resources
= &palmas_rtc_resources
[0],
71 .num_resources
= ARRAY_SIZE(palmas_rtc_resources
),
74 .name
= "palmas-pwrbutton",
75 .id
= PALMAS_PWRBUTTON_ID
,
78 .name
= "palmas-gpadc",
79 .id
= PALMAS_GPADC_ID
,
82 .name
= "palmas-resource",
83 .id
= PALMAS_RESOURCE_ID
,
99 static const struct regmap_config palmas_regmap_config
[PALMAS_NUM_CLIENTS
] = {
103 .max_register
= PALMAS_BASE_TO_REG(PALMAS_PU_PD_OD_BASE
,
104 PALMAS_PRIMARY_SECONDARY_PAD3
),
109 .max_register
= PALMAS_BASE_TO_REG(PALMAS_GPADC_BASE
,
110 PALMAS_GPADC_SMPS_VSEL_MONITORING
),
115 .max_register
= PALMAS_BASE_TO_REG(PALMAS_TRIM_GPADC_BASE
,
116 PALMAS_GPADC_TRIM16
),
120 static const struct regmap_irq palmas_irqs
[] = {
122 [PALMAS_CHARG_DET_N_VBUS_OVV_IRQ
] = {
123 .mask
= PALMAS_INT1_STATUS_CHARG_DET_N_VBUS_OVV
,
125 [PALMAS_PWRON_IRQ
] = {
126 .mask
= PALMAS_INT1_STATUS_PWRON
,
128 [PALMAS_LONG_PRESS_KEY_IRQ
] = {
129 .mask
= PALMAS_INT1_STATUS_LONG_PRESS_KEY
,
131 [PALMAS_RPWRON_IRQ
] = {
132 .mask
= PALMAS_INT1_STATUS_RPWRON
,
134 [PALMAS_PWRDOWN_IRQ
] = {
135 .mask
= PALMAS_INT1_STATUS_PWRDOWN
,
137 [PALMAS_HOTDIE_IRQ
] = {
138 .mask
= PALMAS_INT1_STATUS_HOTDIE
,
140 [PALMAS_VSYS_MON_IRQ
] = {
141 .mask
= PALMAS_INT1_STATUS_VSYS_MON
,
143 [PALMAS_VBAT_MON_IRQ
] = {
144 .mask
= PALMAS_INT1_STATUS_VBAT_MON
,
147 [PALMAS_RTC_ALARM_IRQ
] = {
148 .mask
= PALMAS_INT2_STATUS_RTC_ALARM
,
151 [PALMAS_RTC_TIMER_IRQ
] = {
152 .mask
= PALMAS_INT2_STATUS_RTC_TIMER
,
156 .mask
= PALMAS_INT2_STATUS_WDT
,
159 [PALMAS_BATREMOVAL_IRQ
] = {
160 .mask
= PALMAS_INT2_STATUS_BATREMOVAL
,
163 [PALMAS_RESET_IN_IRQ
] = {
164 .mask
= PALMAS_INT2_STATUS_RESET_IN
,
167 [PALMAS_FBI_BB_IRQ
] = {
168 .mask
= PALMAS_INT2_STATUS_FBI_BB
,
171 [PALMAS_SHORT_IRQ
] = {
172 .mask
= PALMAS_INT2_STATUS_SHORT
,
175 [PALMAS_VAC_ACOK_IRQ
] = {
176 .mask
= PALMAS_INT2_STATUS_VAC_ACOK
,
180 [PALMAS_GPADC_AUTO_0_IRQ
] = {
181 .mask
= PALMAS_INT3_STATUS_GPADC_AUTO_0
,
184 [PALMAS_GPADC_AUTO_1_IRQ
] = {
185 .mask
= PALMAS_INT3_STATUS_GPADC_AUTO_1
,
188 [PALMAS_GPADC_EOC_SW_IRQ
] = {
189 .mask
= PALMAS_INT3_STATUS_GPADC_EOC_SW
,
192 [PALMAS_GPADC_EOC_RT_IRQ
] = {
193 .mask
= PALMAS_INT3_STATUS_GPADC_EOC_RT
,
196 [PALMAS_ID_OTG_IRQ
] = {
197 .mask
= PALMAS_INT3_STATUS_ID_OTG
,
201 .mask
= PALMAS_INT3_STATUS_ID
,
204 [PALMAS_VBUS_OTG_IRQ
] = {
205 .mask
= PALMAS_INT3_STATUS_VBUS_OTG
,
208 [PALMAS_VBUS_IRQ
] = {
209 .mask
= PALMAS_INT3_STATUS_VBUS
,
213 [PALMAS_GPIO_0_IRQ
] = {
214 .mask
= PALMAS_INT4_STATUS_GPIO_0
,
217 [PALMAS_GPIO_1_IRQ
] = {
218 .mask
= PALMAS_INT4_STATUS_GPIO_1
,
221 [PALMAS_GPIO_2_IRQ
] = {
222 .mask
= PALMAS_INT4_STATUS_GPIO_2
,
225 [PALMAS_GPIO_3_IRQ
] = {
226 .mask
= PALMAS_INT4_STATUS_GPIO_3
,
229 [PALMAS_GPIO_4_IRQ
] = {
230 .mask
= PALMAS_INT4_STATUS_GPIO_4
,
233 [PALMAS_GPIO_5_IRQ
] = {
234 .mask
= PALMAS_INT4_STATUS_GPIO_5
,
237 [PALMAS_GPIO_6_IRQ
] = {
238 .mask
= PALMAS_INT4_STATUS_GPIO_6
,
241 [PALMAS_GPIO_7_IRQ
] = {
242 .mask
= PALMAS_INT4_STATUS_GPIO_7
,
247 static struct regmap_irq_chip palmas_irq_chip
= {
250 .num_irqs
= ARRAY_SIZE(palmas_irqs
),
254 .status_base
= PALMAS_BASE_TO_REG(PALMAS_INTERRUPT_BASE
,
256 .mask_base
= PALMAS_BASE_TO_REG(PALMAS_INTERRUPT_BASE
,
260 static void palmas_dt_to_pdata(struct device_node
*node
,
261 struct palmas_platform_data
*pdata
)
266 ret
= of_property_read_u32(node
, "ti,mux_pad1", &prop
);
268 pdata
->mux_from_pdata
= 1;
272 ret
= of_property_read_u32(node
, "ti,mux_pad2", &prop
);
274 pdata
->mux_from_pdata
= 1;
278 /* The default for this register is all masked */
279 ret
= of_property_read_u32(node
, "ti,power_ctrl", &prop
);
281 pdata
->power_ctrl
= prop
;
283 pdata
->power_ctrl
= PALMAS_POWER_CTRL_NSLEEP_MASK
|
284 PALMAS_POWER_CTRL_ENABLE1_MASK
|
285 PALMAS_POWER_CTRL_ENABLE2_MASK
;
288 static int palmas_i2c_probe(struct i2c_client
*i2c
,
289 const struct i2c_device_id
*id
)
291 struct palmas
*palmas
;
292 struct palmas_platform_data
*pdata
;
293 struct device_node
*node
= i2c
->dev
.of_node
;
295 unsigned int reg
, addr
;
297 struct mfd_cell
*children
;
299 pdata
= dev_get_platdata(&i2c
->dev
);
301 if (node
&& !pdata
) {
302 pdata
= devm_kzalloc(&i2c
->dev
, sizeof(*pdata
), GFP_KERNEL
);
307 palmas_dt_to_pdata(node
, pdata
);
313 palmas
= devm_kzalloc(&i2c
->dev
, sizeof(struct palmas
), GFP_KERNEL
);
317 i2c_set_clientdata(i2c
, palmas
);
318 palmas
->dev
= &i2c
->dev
;
319 palmas
->id
= id
->driver_data
;
320 palmas
->irq
= i2c
->irq
;
322 for (i
= 0; i
< PALMAS_NUM_CLIENTS
; i
++) {
324 palmas
->i2c_clients
[i
] = i2c
;
326 palmas
->i2c_clients
[i
] =
327 i2c_new_dummy(i2c
->adapter
,
329 if (!palmas
->i2c_clients
[i
]) {
331 "can't attach client %d\n", i
);
336 palmas
->regmap
[i
] = devm_regmap_init_i2c(palmas
->i2c_clients
[i
],
337 &palmas_regmap_config
[i
]);
338 if (IS_ERR(palmas
->regmap
[i
])) {
339 ret
= PTR_ERR(palmas
->regmap
[i
]);
341 "Failed to allocate regmap %d, err: %d\n",
347 /* Change IRQ into clear on read mode for efficiency */
348 slave
= PALMAS_BASE_TO_SLAVE(PALMAS_INTERRUPT_BASE
);
349 addr
= PALMAS_BASE_TO_REG(PALMAS_INTERRUPT_BASE
, PALMAS_INT_CTRL
);
350 reg
= PALMAS_INT_CTRL_INT_CLEAR
;
352 regmap_write(palmas
->regmap
[slave
], addr
, reg
);
354 ret
= regmap_add_irq_chip(palmas
->regmap
[slave
], palmas
->irq
,
355 IRQF_ONESHOT
| IRQF_TRIGGER_LOW
, 0, &palmas_irq_chip
,
360 slave
= PALMAS_BASE_TO_SLAVE(PALMAS_PU_PD_OD_BASE
);
361 addr
= PALMAS_BASE_TO_REG(PALMAS_PU_PD_OD_BASE
,
362 PALMAS_PRIMARY_SECONDARY_PAD1
);
364 if (pdata
->mux_from_pdata
) {
366 ret
= regmap_write(palmas
->regmap
[slave
], addr
, reg
);
370 ret
= regmap_read(palmas
->regmap
[slave
], addr
, ®
);
375 if (!(reg
& PALMAS_PRIMARY_SECONDARY_PAD1_GPIO_0
))
376 palmas
->gpio_muxed
|= PALMAS_GPIO_0_MUXED
;
377 if (!(reg
& PALMAS_PRIMARY_SECONDARY_PAD1_GPIO_1_MASK
))
378 palmas
->gpio_muxed
|= PALMAS_GPIO_1_MUXED
;
379 else if ((reg
& PALMAS_PRIMARY_SECONDARY_PAD1_GPIO_1_MASK
) ==
380 (2 << PALMAS_PRIMARY_SECONDARY_PAD1_GPIO_1_SHIFT
))
381 palmas
->led_muxed
|= PALMAS_LED1_MUXED
;
382 else if ((reg
& PALMAS_PRIMARY_SECONDARY_PAD1_GPIO_1_MASK
) ==
383 (3 << PALMAS_PRIMARY_SECONDARY_PAD1_GPIO_1_SHIFT
))
384 palmas
->pwm_muxed
|= PALMAS_PWM1_MUXED
;
385 if (!(reg
& PALMAS_PRIMARY_SECONDARY_PAD1_GPIO_2_MASK
))
386 palmas
->gpio_muxed
|= PALMAS_GPIO_2_MUXED
;
387 else if ((reg
& PALMAS_PRIMARY_SECONDARY_PAD1_GPIO_2_MASK
) ==
388 (2 << PALMAS_PRIMARY_SECONDARY_PAD1_GPIO_2_SHIFT
))
389 palmas
->led_muxed
|= PALMAS_LED2_MUXED
;
390 else if ((reg
& PALMAS_PRIMARY_SECONDARY_PAD1_GPIO_2_MASK
) ==
391 (3 << PALMAS_PRIMARY_SECONDARY_PAD1_GPIO_2_SHIFT
))
392 palmas
->pwm_muxed
|= PALMAS_PWM2_MUXED
;
393 if (!(reg
& PALMAS_PRIMARY_SECONDARY_PAD1_GPIO_3
))
394 palmas
->gpio_muxed
|= PALMAS_GPIO_3_MUXED
;
396 addr
= PALMAS_BASE_TO_REG(PALMAS_PU_PD_OD_BASE
,
397 PALMAS_PRIMARY_SECONDARY_PAD2
);
399 if (pdata
->mux_from_pdata
) {
401 ret
= regmap_write(palmas
->regmap
[slave
], addr
, reg
);
405 ret
= regmap_read(palmas
->regmap
[slave
], addr
, ®
);
410 if (!(reg
& PALMAS_PRIMARY_SECONDARY_PAD2_GPIO_4
))
411 palmas
->gpio_muxed
|= PALMAS_GPIO_4_MUXED
;
412 if (!(reg
& PALMAS_PRIMARY_SECONDARY_PAD2_GPIO_5_MASK
))
413 palmas
->gpio_muxed
|= PALMAS_GPIO_5_MUXED
;
414 if (!(reg
& PALMAS_PRIMARY_SECONDARY_PAD2_GPIO_6
))
415 palmas
->gpio_muxed
|= PALMAS_GPIO_6_MUXED
;
416 if (!(reg
& PALMAS_PRIMARY_SECONDARY_PAD2_GPIO_7_MASK
))
417 palmas
->gpio_muxed
|= PALMAS_GPIO_7_MUXED
;
419 dev_info(palmas
->dev
, "Muxing GPIO %x, PWM %x, LED %x\n",
420 palmas
->gpio_muxed
, palmas
->pwm_muxed
,
423 reg
= pdata
->power_ctrl
;
425 slave
= PALMAS_BASE_TO_SLAVE(PALMAS_PMU_CONTROL_BASE
);
426 addr
= PALMAS_BASE_TO_REG(PALMAS_PMU_CONTROL_BASE
, PALMAS_POWER_CTRL
);
428 ret
= regmap_write(palmas
->regmap
[slave
], addr
, reg
);
433 * If we are probing with DT do this the DT way and return here
434 * otherwise continue and add devices using mfd helpers.
437 ret
= of_platform_populate(node
, NULL
, NULL
, &i2c
->dev
);
444 children
= kmemdup(palmas_children
, sizeof(palmas_children
),
451 children
[PALMAS_PMIC_ID
].platform_data
= pdata
->pmic_pdata
;
452 children
[PALMAS_PMIC_ID
].pdata_size
= sizeof(*pdata
->pmic_pdata
);
454 children
[PALMAS_GPADC_ID
].platform_data
= pdata
->gpadc_pdata
;
455 children
[PALMAS_GPADC_ID
].pdata_size
= sizeof(*pdata
->gpadc_pdata
);
457 children
[PALMAS_RESOURCE_ID
].platform_data
= pdata
->resource_pdata
;
458 children
[PALMAS_RESOURCE_ID
].pdata_size
=
459 sizeof(*pdata
->resource_pdata
);
461 children
[PALMAS_USB_ID
].platform_data
= pdata
->usb_pdata
;
462 children
[PALMAS_USB_ID
].pdata_size
= sizeof(*pdata
->usb_pdata
);
464 children
[PALMAS_CLK_ID
].platform_data
= pdata
->clk_pdata
;
465 children
[PALMAS_CLK_ID
].pdata_size
= sizeof(*pdata
->clk_pdata
);
467 ret
= mfd_add_devices(palmas
->dev
, -1,
468 children
, ARRAY_SIZE(palmas_children
),
470 regmap_irq_get_domain(palmas
->irq_data
));
479 mfd_remove_devices(palmas
->dev
);
481 regmap_del_irq_chip(palmas
->irq
, palmas
->irq_data
);
486 static int palmas_i2c_remove(struct i2c_client
*i2c
)
488 struct palmas
*palmas
= i2c_get_clientdata(i2c
);
490 mfd_remove_devices(palmas
->dev
);
491 regmap_del_irq_chip(palmas
->irq
, palmas
->irq_data
);
496 static const struct i2c_device_id palmas_i2c_id
[] = {
503 MODULE_DEVICE_TABLE(i2c
, palmas_i2c_id
);
505 static struct of_device_id of_palmas_match_tbl
[] = {
506 { .compatible
= "ti,palmas", },
510 static struct i2c_driver palmas_i2c_driver
= {
513 .of_match_table
= of_palmas_match_tbl
,
514 .owner
= THIS_MODULE
,
516 .probe
= palmas_i2c_probe
,
517 .remove
= palmas_i2c_remove
,
518 .id_table
= palmas_i2c_id
,
521 static int __init
palmas_i2c_init(void)
523 return i2c_add_driver(&palmas_i2c_driver
);
525 /* init early so consumer devices can complete system boot */
526 subsys_initcall(palmas_i2c_init
);
528 static void __exit
palmas_i2c_exit(void)
530 i2c_del_driver(&palmas_i2c_driver
);
532 module_exit(palmas_i2c_exit
);
534 MODULE_AUTHOR("Graeme Gregory <gg@slimlogic.co.uk>");
535 MODULE_DESCRIPTION("Palmas chip family multi-function driver");
536 MODULE_LICENSE("GPL");