2 * Core driver for TPS61050/61052 boost converters, used for while LED
3 * driving, audio power amplification, white LED flash, and generic
4 * boost conversion. Additionally it provides a 1-bit GPIO pin (out or in)
5 * and a flash synchronization pin to synchronize flash events when used as
8 * Copyright (C) 2011 ST-Ericsson SA
9 * Written on behalf of Linaro for ST-Ericsson
11 * Author: Linus Walleij <linus.walleij@linaro.org>
13 * License terms: GNU General Public License (GPL) version 2
16 #include <linux/module.h>
17 #include <linux/init.h>
18 #include <linux/i2c.h>
19 #include <linux/regmap.h>
20 #include <linux/gpio.h>
21 #include <linux/spinlock.h>
22 #include <linux/slab.h>
23 #include <linux/err.h>
24 #include <linux/regulator/driver.h>
25 #include <linux/mfd/core.h>
26 #include <linux/mfd/tps6105x.h>
28 static struct regmap_config tps6105x_regmap_config
= {
31 .max_register
= TPS6105X_REG_3
,
34 static int tps6105x_startup(struct tps6105x
*tps6105x
)
39 ret
= regmap_read(tps6105x
->regmap
, TPS6105X_REG_0
, ®val
);
42 switch (regval
>> TPS6105X_REG0_MODE_SHIFT
) {
43 case TPS6105X_REG0_MODE_SHUTDOWN
:
44 dev_info(&tps6105x
->client
->dev
,
45 "TPS6105x found in SHUTDOWN mode\n");
47 case TPS6105X_REG0_MODE_TORCH
:
48 dev_info(&tps6105x
->client
->dev
,
49 "TPS6105x found in TORCH mode\n");
51 case TPS6105X_REG0_MODE_TORCH_FLASH
:
52 dev_info(&tps6105x
->client
->dev
,
53 "TPS6105x found in FLASH mode\n");
55 case TPS6105X_REG0_MODE_VOLTAGE
:
56 dev_info(&tps6105x
->client
->dev
,
57 "TPS6105x found in VOLTAGE mode\n");
67 * MFD cells - we always have a GPIO cell and we have one cell
68 * which is selected operation mode.
70 static struct mfd_cell tps6105x_gpio_cell
= {
71 .name
= "tps6105x-gpio",
74 static struct mfd_cell tps6105x_leds_cell
= {
75 .name
= "tps6105x-leds",
78 static struct mfd_cell tps6105x_flash_cell
= {
79 .name
= "tps6105x-flash",
82 static struct mfd_cell tps6105x_regulator_cell
= {
83 .name
= "tps6105x-regulator",
86 static int tps6105x_add_device(struct tps6105x
*tps6105x
,
87 struct mfd_cell
*cell
)
89 cell
->platform_data
= tps6105x
;
90 cell
->pdata_size
= sizeof(*tps6105x
);
92 return mfd_add_devices(&tps6105x
->client
->dev
,
93 PLATFORM_DEVID_AUTO
, cell
, 1, NULL
, 0, NULL
);
96 static int tps6105x_probe(struct i2c_client
*client
,
97 const struct i2c_device_id
*id
)
99 struct tps6105x
*tps6105x
;
100 struct tps6105x_platform_data
*pdata
;
103 pdata
= dev_get_platdata(&client
->dev
);
105 dev_err(&client
->dev
, "missing platform data\n");
109 tps6105x
= devm_kmalloc(&client
->dev
, sizeof(*tps6105x
), GFP_KERNEL
);
113 tps6105x
->regmap
= devm_regmap_init_i2c(client
, &tps6105x_regmap_config
);
114 if (IS_ERR(tps6105x
->regmap
))
115 return PTR_ERR(tps6105x
->regmap
);
117 i2c_set_clientdata(client
, tps6105x
);
118 tps6105x
->client
= client
;
119 tps6105x
->pdata
= pdata
;
121 ret
= tps6105x_startup(tps6105x
);
123 dev_err(&client
->dev
, "chip initialization failed\n");
127 ret
= tps6105x_add_device(tps6105x
, &tps6105x_gpio_cell
);
131 switch (pdata
->mode
) {
132 case TPS6105X_MODE_SHUTDOWN
:
133 dev_info(&client
->dev
,
134 "present, not used for anything, only GPIO\n");
136 case TPS6105X_MODE_TORCH
:
137 ret
= tps6105x_add_device(tps6105x
, &tps6105x_leds_cell
);
139 case TPS6105X_MODE_TORCH_FLASH
:
140 ret
= tps6105x_add_device(tps6105x
, &tps6105x_flash_cell
);
142 case TPS6105X_MODE_VOLTAGE
:
143 ret
= tps6105x_add_device(tps6105x
, &tps6105x_regulator_cell
);
146 dev_warn(&client
->dev
, "invalid mode: %d\n", pdata
->mode
);
151 mfd_remove_devices(&client
->dev
);
156 static int tps6105x_remove(struct i2c_client
*client
)
158 struct tps6105x
*tps6105x
= i2c_get_clientdata(client
);
160 mfd_remove_devices(&client
->dev
);
162 /* Put chip in shutdown mode */
163 regmap_update_bits(tps6105x
->regmap
, TPS6105X_REG_0
,
164 TPS6105X_REG0_MODE_MASK
,
165 TPS6105X_MODE_SHUTDOWN
<< TPS6105X_REG0_MODE_SHIFT
);
170 static const struct i2c_device_id tps6105x_id
[] = {
175 MODULE_DEVICE_TABLE(i2c
, tps6105x_id
);
177 static struct i2c_driver tps6105x_driver
= {
181 .probe
= tps6105x_probe
,
182 .remove
= tps6105x_remove
,
183 .id_table
= tps6105x_id
,
186 static int __init
tps6105x_init(void)
188 return i2c_add_driver(&tps6105x_driver
);
190 subsys_initcall(tps6105x_init
);
192 static void __exit
tps6105x_exit(void)
194 i2c_del_driver(&tps6105x_driver
);
196 module_exit(tps6105x_exit
);
198 MODULE_AUTHOR("Linus Walleij");
199 MODULE_DESCRIPTION("TPS6105x White LED Boost Converter Driver");
200 MODULE_LICENSE("GPL v2");