Blame view
drivers/mfd/tc3589x.c
11.8 KB
b4ecd326b mfd: Add Toshiba'... |
1 2 3 4 5 6 7 8 9 10 11 |
/* * Copyright (C) ST-Ericsson SA 2010 * * License Terms: GNU General Public License, version 2 * Author: Hanumath Prasad <hanumath.prasad@stericsson.com> for ST-Ericsson * Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson */ #include <linux/module.h> #include <linux/interrupt.h> #include <linux/irq.h> |
15e27b108 mfd: Provide the ... |
12 |
#include <linux/irqdomain.h> |
b4ecd326b mfd: Add Toshiba'... |
13 14 |
#include <linux/slab.h> #include <linux/i2c.h> |
a435ae1d5 mfd: Enable the t... |
15 |
#include <linux/of.h> |
a381b13e2 mfd: tc3589x: Ref... |
16 |
#include <linux/of_device.h> |
b4ecd326b mfd: Add Toshiba'... |
17 |
#include <linux/mfd/core.h> |
c6eda6c5e mfd/tc35892: rena... |
18 |
#include <linux/mfd/tc3589x.h> |
a381b13e2 mfd: tc3589x: Ref... |
19 |
#include <linux/err.h> |
b4ecd326b mfd: Add Toshiba'... |
20 |
|
e64c1eb47 mfd: tc3589x: Det... |
21 22 23 24 25 26 27 28 29 30 31 32 |
/** * enum tc3589x_version - indicates the TC3589x version */ enum tc3589x_version { TC3589X_TC35890, TC3589X_TC35892, TC3589X_TC35893, TC3589X_TC35894, TC3589X_TC35895, TC3589X_TC35896, TC3589X_UNKNOWN, }; |
593e9d70f mfd/tc3589x: add ... |
33 34 |
#define TC3589x_CLKMODE_MODCTL_SLEEP 0x0 #define TC3589x_CLKMODE_MODCTL_OPERATION (1 << 0) |
b4ecd326b mfd: Add Toshiba'... |
35 |
/** |
20406ebff mfd/tc3589x: rena... |
36 37 |
* tc3589x_reg_read() - read a single TC3589x register * @tc3589x: Device to read from |
b4ecd326b mfd: Add Toshiba'... |
38 39 |
* @reg: Register to read */ |
20406ebff mfd/tc3589x: rena... |
40 |
int tc3589x_reg_read(struct tc3589x *tc3589x, u8 reg) |
b4ecd326b mfd: Add Toshiba'... |
41 42 |
{ int ret; |
20406ebff mfd/tc3589x: rena... |
43 |
ret = i2c_smbus_read_byte_data(tc3589x->i2c, reg); |
b4ecd326b mfd: Add Toshiba'... |
44 |
if (ret < 0) |
20406ebff mfd/tc3589x: rena... |
45 46 |
dev_err(tc3589x->dev, "failed to read reg %#x: %d ", |
b4ecd326b mfd: Add Toshiba'... |
47 48 49 50 |
reg, ret); return ret; } |
20406ebff mfd/tc3589x: rena... |
51 |
EXPORT_SYMBOL_GPL(tc3589x_reg_read); |
b4ecd326b mfd: Add Toshiba'... |
52 53 |
/** |
20406ebff mfd/tc3589x: rena... |
54 55 |
* tc3589x_reg_read() - write a single TC3589x register * @tc3589x: Device to write to |
b4ecd326b mfd: Add Toshiba'... |
56 57 58 |
* @reg: Register to read * @data: Value to write */ |
20406ebff mfd/tc3589x: rena... |
59 |
int tc3589x_reg_write(struct tc3589x *tc3589x, u8 reg, u8 data) |
b4ecd326b mfd: Add Toshiba'... |
60 61 |
{ int ret; |
20406ebff mfd/tc3589x: rena... |
62 |
ret = i2c_smbus_write_byte_data(tc3589x->i2c, reg, data); |
b4ecd326b mfd: Add Toshiba'... |
63 |
if (ret < 0) |
20406ebff mfd/tc3589x: rena... |
64 65 |
dev_err(tc3589x->dev, "failed to write reg %#x: %d ", |
b4ecd326b mfd: Add Toshiba'... |
66 67 68 69 |
reg, ret); return ret; } |
20406ebff mfd/tc3589x: rena... |
70 |
EXPORT_SYMBOL_GPL(tc3589x_reg_write); |
b4ecd326b mfd: Add Toshiba'... |
71 72 |
/** |
20406ebff mfd/tc3589x: rena... |
73 74 |
* tc3589x_block_read() - read multiple TC3589x registers * @tc3589x: Device to read from |
b4ecd326b mfd: Add Toshiba'... |
75 76 77 78 |
* @reg: First register * @length: Number of registers * @values: Buffer to write to */ |
20406ebff mfd/tc3589x: rena... |
79 |
int tc3589x_block_read(struct tc3589x *tc3589x, u8 reg, u8 length, u8 *values) |
b4ecd326b mfd: Add Toshiba'... |
80 81 |
{ int ret; |
20406ebff mfd/tc3589x: rena... |
82 |
ret = i2c_smbus_read_i2c_block_data(tc3589x->i2c, reg, length, values); |
b4ecd326b mfd: Add Toshiba'... |
83 |
if (ret < 0) |
20406ebff mfd/tc3589x: rena... |
84 85 |
dev_err(tc3589x->dev, "failed to read regs %#x: %d ", |
b4ecd326b mfd: Add Toshiba'... |
86 87 88 89 |
reg, ret); return ret; } |
20406ebff mfd/tc3589x: rena... |
90 |
EXPORT_SYMBOL_GPL(tc3589x_block_read); |
b4ecd326b mfd: Add Toshiba'... |
91 92 |
/** |
20406ebff mfd/tc3589x: rena... |
93 94 |
* tc3589x_block_write() - write multiple TC3589x registers * @tc3589x: Device to write to |
b4ecd326b mfd: Add Toshiba'... |
95 96 97 98 |
* @reg: First register * @length: Number of registers * @values: Values to write */ |
20406ebff mfd/tc3589x: rena... |
99 |
int tc3589x_block_write(struct tc3589x *tc3589x, u8 reg, u8 length, |
b4ecd326b mfd: Add Toshiba'... |
100 101 102 |
const u8 *values) { int ret; |
20406ebff mfd/tc3589x: rena... |
103 |
ret = i2c_smbus_write_i2c_block_data(tc3589x->i2c, reg, length, |
b4ecd326b mfd: Add Toshiba'... |
104 105 |
values); if (ret < 0) |
20406ebff mfd/tc3589x: rena... |
106 107 |
dev_err(tc3589x->dev, "failed to write regs %#x: %d ", |
b4ecd326b mfd: Add Toshiba'... |
108 109 110 111 |
reg, ret); return ret; } |
20406ebff mfd/tc3589x: rena... |
112 |
EXPORT_SYMBOL_GPL(tc3589x_block_write); |
b4ecd326b mfd: Add Toshiba'... |
113 114 |
/** |
20406ebff mfd/tc3589x: rena... |
115 116 |
* tc3589x_set_bits() - set the value of a bitfield in a TC3589x register * @tc3589x: Device to write to |
b4ecd326b mfd: Add Toshiba'... |
117 118 119 120 |
* @reg: Register to write * @mask: Mask of bits to set * @values: Value to set */ |
20406ebff mfd/tc3589x: rena... |
121 |
int tc3589x_set_bits(struct tc3589x *tc3589x, u8 reg, u8 mask, u8 val) |
b4ecd326b mfd: Add Toshiba'... |
122 123 |
{ int ret; |
20406ebff mfd/tc3589x: rena... |
124 |
mutex_lock(&tc3589x->lock); |
b4ecd326b mfd: Add Toshiba'... |
125 |
|
20406ebff mfd/tc3589x: rena... |
126 |
ret = tc3589x_reg_read(tc3589x, reg); |
b4ecd326b mfd: Add Toshiba'... |
127 128 129 130 131 |
if (ret < 0) goto out; ret &= ~mask; ret |= val; |
20406ebff mfd/tc3589x: rena... |
132 |
ret = tc3589x_reg_write(tc3589x, reg, ret); |
b4ecd326b mfd: Add Toshiba'... |
133 134 |
out: |
20406ebff mfd/tc3589x: rena... |
135 |
mutex_unlock(&tc3589x->lock); |
b4ecd326b mfd: Add Toshiba'... |
136 137 |
return ret; } |
20406ebff mfd/tc3589x: rena... |
138 |
EXPORT_SYMBOL_GPL(tc3589x_set_bits); |
b4ecd326b mfd: Add Toshiba'... |
139 140 141 |
static struct resource gpio_resources[] = { { |
20406ebff mfd/tc3589x: rena... |
142 143 |
.start = TC3589x_INT_GPIIRQ, .end = TC3589x_INT_GPIIRQ, |
b4ecd326b mfd: Add Toshiba'... |
144 145 146 |
.flags = IORESOURCE_IRQ, }, }; |
09c730a48 input/tc3589x: ad... |
147 148 149 150 151 152 153 |
static struct resource keypad_resources[] = { { .start = TC3589x_INT_KBDIRQ, .end = TC3589x_INT_KBDIRQ, .flags = IORESOURCE_IRQ, }, }; |
afb580a94 mfd: toshiba: Con... |
154 |
static const struct mfd_cell tc3589x_dev_gpio[] = { |
b4ecd326b mfd: Add Toshiba'... |
155 |
{ |
20406ebff mfd/tc3589x: rena... |
156 |
.name = "tc3589x-gpio", |
b4ecd326b mfd: Add Toshiba'... |
157 158 |
.num_resources = ARRAY_SIZE(gpio_resources), .resources = &gpio_resources[0], |
a381b13e2 mfd: tc3589x: Ref... |
159 |
.of_compatible = "toshiba,tc3589x-gpio", |
b4ecd326b mfd: Add Toshiba'... |
160 161 |
}, }; |
afb580a94 mfd: toshiba: Con... |
162 |
static const struct mfd_cell tc3589x_dev_keypad[] = { |
09c730a48 input/tc3589x: ad... |
163 164 165 166 |
{ .name = "tc3589x-keypad", .num_resources = ARRAY_SIZE(keypad_resources), .resources = &keypad_resources[0], |
a381b13e2 mfd: tc3589x: Ref... |
167 |
.of_compatible = "toshiba,tc3589x-keypad", |
09c730a48 input/tc3589x: ad... |
168 169 |
}, }; |
20406ebff mfd/tc3589x: rena... |
170 |
static irqreturn_t tc3589x_irq(int irq, void *data) |
b4ecd326b mfd: Add Toshiba'... |
171 |
{ |
20406ebff mfd/tc3589x: rena... |
172 |
struct tc3589x *tc3589x = data; |
b4ecd326b mfd: Add Toshiba'... |
173 |
int status; |
bd77efd0c mfd/tc3589x: fix ... |
174 |
again: |
20406ebff mfd/tc3589x: rena... |
175 |
status = tc3589x_reg_read(tc3589x, TC3589x_IRQST); |
b4ecd326b mfd: Add Toshiba'... |
176 177 178 179 180 |
if (status < 0) return IRQ_NONE; while (status) { int bit = __ffs(status); |
15e27b108 mfd: Provide the ... |
181 |
int virq = irq_create_mapping(tc3589x->domain, bit); |
b4ecd326b mfd: Add Toshiba'... |
182 |
|
15e27b108 mfd: Provide the ... |
183 |
handle_nested_irq(virq); |
b4ecd326b mfd: Add Toshiba'... |
184 185 186 187 188 189 |
status &= ~(1 << bit); } /* * A dummy read or write (to any register) appears to be necessary to * have the last interrupt clear (for example, GPIO IC write) take |
bd77efd0c mfd/tc3589x: fix ... |
190 191 |
* effect. In such a case, recheck for any interrupt which is still * pending. |
b4ecd326b mfd: Add Toshiba'... |
192 |
*/ |
bd77efd0c mfd/tc3589x: fix ... |
193 194 195 |
status = tc3589x_reg_read(tc3589x, TC3589x_IRQST); if (status) goto again; |
b4ecd326b mfd: Add Toshiba'... |
196 197 198 |
return IRQ_HANDLED; } |
15e27b108 mfd: Provide the ... |
199 200 |
static int tc3589x_irq_map(struct irq_domain *d, unsigned int virq, irq_hw_number_t hwirq) |
b4ecd326b mfd: Add Toshiba'... |
201 |
{ |
15e27b108 mfd: Provide the ... |
202 |
struct tc3589x *tc3589x = d->host_data; |
b4ecd326b mfd: Add Toshiba'... |
203 |
|
15e27b108 mfd: Provide the ... |
204 205 206 207 |
irq_set_chip_data(virq, tc3589x); irq_set_chip_and_handler(virq, &dummy_irq_chip, handle_edge_irq); irq_set_nested_thread(virq, 1); |
15e27b108 mfd: Provide the ... |
208 |
irq_set_noprobe(virq); |
b4ecd326b mfd: Add Toshiba'... |
209 210 211 |
return 0; } |
15e27b108 mfd: Provide the ... |
212 |
static void tc3589x_irq_unmap(struct irq_domain *d, unsigned int virq) |
b4ecd326b mfd: Add Toshiba'... |
213 |
{ |
15e27b108 mfd: Provide the ... |
214 215 216 |
irq_set_chip_and_handler(virq, NULL, NULL); irq_set_chip_data(virq, NULL); } |
7ce7b26f8 mfd: Constify reg... |
217 |
static const struct irq_domain_ops tc3589x_irq_ops = { |
1f0529b4d mfd: tc3589x: Use... |
218 |
.map = tc3589x_irq_map, |
15e27b108 mfd: Provide the ... |
219 |
.unmap = tc3589x_irq_unmap, |
627918ed1 mfd: tc3589x: Tra... |
220 |
.xlate = irq_domain_xlate_onecell, |
15e27b108 mfd: Provide the ... |
221 |
}; |
a435ae1d5 mfd: Enable the t... |
222 |
static int tc3589x_irq_init(struct tc3589x *tc3589x, struct device_node *np) |
15e27b108 mfd: Provide the ... |
223 |
{ |
1f0529b4d mfd: tc3589x: Use... |
224 |
tc3589x->domain = irq_domain_add_simple( |
90f2d0f7b mfd: tc3589x: get... |
225 |
np, TC3589x_NR_INTERNAL_IRQS, 0, |
1f0529b4d mfd: tc3589x: Use... |
226 |
&tc3589x_irq_ops, tc3589x); |
15e27b108 mfd: Provide the ... |
227 228 229 230 231 232 233 234 |
if (!tc3589x->domain) { dev_err(tc3589x->dev, "Failed to create irqdomain "); return -ENOSYS; } return 0; |
b4ecd326b mfd: Add Toshiba'... |
235 |
} |
20406ebff mfd/tc3589x: rena... |
236 |
static int tc3589x_chip_init(struct tc3589x *tc3589x) |
b4ecd326b mfd: Add Toshiba'... |
237 238 |
{ int manf, ver, ret; |
20406ebff mfd/tc3589x: rena... |
239 |
manf = tc3589x_reg_read(tc3589x, TC3589x_MANFCODE); |
b4ecd326b mfd: Add Toshiba'... |
240 241 |
if (manf < 0) return manf; |
20406ebff mfd/tc3589x: rena... |
242 |
ver = tc3589x_reg_read(tc3589x, TC3589x_VERSION); |
b4ecd326b mfd: Add Toshiba'... |
243 244 |
if (ver < 0) return ver; |
20406ebff mfd/tc3589x: rena... |
245 246 247 |
if (manf != TC3589x_MANFCODE_MAGIC) { dev_err(tc3589x->dev, "unknown manufacturer: %#x ", manf); |
b4ecd326b mfd: Add Toshiba'... |
248 249 |
return -EINVAL; } |
20406ebff mfd/tc3589x: rena... |
250 251 |
dev_info(tc3589x->dev, "manufacturer: %#x, version: %#x ", manf, ver); |
b4ecd326b mfd: Add Toshiba'... |
252 |
|
523bc3820 mfd/tc3589x: undo... |
253 254 255 256 257 |
/* * Put everything except the IRQ module into reset; * also spare the GPIO module for any pin initialization * done during pre-kernel boot */ |
20406ebff mfd/tc3589x: rena... |
258 259 260 |
ret = tc3589x_reg_write(tc3589x, TC3589x_RSTCTRL, TC3589x_RSTCTRL_TIMRST | TC3589x_RSTCTRL_ROTRST |
523bc3820 mfd/tc3589x: undo... |
261 |
| TC3589x_RSTCTRL_KBDRST); |
b4ecd326b mfd: Add Toshiba'... |
262 263 264 265 |
if (ret < 0) return ret; /* Clear the reset interrupt. */ |
20406ebff mfd/tc3589x: rena... |
266 |
return tc3589x_reg_write(tc3589x, TC3589x_RSTINTCLR, 0x1); |
b4ecd326b mfd: Add Toshiba'... |
267 |
} |
f791be492 mfd: remove use o... |
268 |
static int tc3589x_device_init(struct tc3589x *tc3589x) |
611b7590a mfd/tc3589x: add ... |
269 270 271 272 273 274 |
{ int ret = 0; unsigned int blocks = tc3589x->pdata->block; if (blocks & TC3589x_BLOCK_GPIO) { ret = mfd_add_devices(tc3589x->dev, -1, tc3589x_dev_gpio, |
55692af5e mfd: core: Push i... |
275 |
ARRAY_SIZE(tc3589x_dev_gpio), NULL, |
90f2d0f7b mfd: tc3589x: get... |
276 |
0, tc3589x->domain); |
611b7590a mfd/tc3589x: add ... |
277 278 279 280 281 282 283 284 |
if (ret) { dev_err(tc3589x->dev, "failed to add gpio child "); return ret; } dev_info(tc3589x->dev, "added gpio block "); } |
09c730a48 input/tc3589x: ad... |
285 286 |
if (blocks & TC3589x_BLOCK_KEYPAD) { ret = mfd_add_devices(tc3589x->dev, -1, tc3589x_dev_keypad, |
55692af5e mfd: core: Push i... |
287 |
ARRAY_SIZE(tc3589x_dev_keypad), NULL, |
90f2d0f7b mfd: tc3589x: get... |
288 |
0, tc3589x->domain); |
09c730a48 input/tc3589x: ad... |
289 290 291 292 293 294 295 296 |
if (ret) { dev_err(tc3589x->dev, "failed to keypad child "); return ret; } dev_info(tc3589x->dev, "added keypad block "); } |
611b7590a mfd/tc3589x: add ... |
297 |
|
09c730a48 input/tc3589x: ad... |
298 |
return ret; |
611b7590a mfd/tc3589x: add ... |
299 |
} |
a381b13e2 mfd: tc3589x: Ref... |
300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 |
static const struct of_device_id tc3589x_match[] = { /* Legacy compatible string */ { .compatible = "tc3589x", .data = (void *) TC3589X_UNKNOWN }, { .compatible = "toshiba,tc35890", .data = (void *) TC3589X_TC35890 }, { .compatible = "toshiba,tc35892", .data = (void *) TC3589X_TC35892 }, { .compatible = "toshiba,tc35893", .data = (void *) TC3589X_TC35893 }, { .compatible = "toshiba,tc35894", .data = (void *) TC3589X_TC35894 }, { .compatible = "toshiba,tc35895", .data = (void *) TC3589X_TC35895 }, { .compatible = "toshiba,tc35896", .data = (void *) TC3589X_TC35896 }, { } }; MODULE_DEVICE_TABLE(of, tc3589x_match); static struct tc3589x_platform_data * tc3589x_of_probe(struct device *dev, enum tc3589x_version *version) |
a435ae1d5 mfd: Enable the t... |
316 |
{ |
a381b13e2 mfd: tc3589x: Ref... |
317 318 |
struct device_node *np = dev->of_node; struct tc3589x_platform_data *pdata; |
a435ae1d5 mfd: Enable the t... |
319 |
struct device_node *child; |
a381b13e2 mfd: tc3589x: Ref... |
320 321 322 323 324 325 326 327 328 329 |
const struct of_device_id *of_id; pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); if (!pdata) return ERR_PTR(-ENOMEM); of_id = of_match_device(tc3589x_match, dev); if (!of_id) return ERR_PTR(-ENODEV); *version = (enum tc3589x_version) of_id->data; |
a435ae1d5 mfd: Enable the t... |
330 331 |
for_each_child_of_node(np, child) { |
a381b13e2 mfd: tc3589x: Ref... |
332 |
if (of_device_is_compatible(child, "toshiba,tc3589x-gpio")) |
a435ae1d5 mfd: Enable the t... |
333 |
pdata->block |= TC3589x_BLOCK_GPIO; |
a381b13e2 mfd: tc3589x: Ref... |
334 |
if (of_device_is_compatible(child, "toshiba,tc3589x-keypad")) |
a435ae1d5 mfd: Enable the t... |
335 |
pdata->block |= TC3589x_BLOCK_KEYPAD; |
a435ae1d5 mfd: Enable the t... |
336 |
} |
a381b13e2 mfd: tc3589x: Ref... |
337 |
return pdata; |
a435ae1d5 mfd: Enable the t... |
338 |
} |
f791be492 mfd: remove use o... |
339 |
static int tc3589x_probe(struct i2c_client *i2c, |
b4ecd326b mfd: Add Toshiba'... |
340 341 |
const struct i2c_device_id *id) { |
a435ae1d5 mfd: Enable the t... |
342 |
struct device_node *np = i2c->dev.of_node; |
a381b13e2 mfd: tc3589x: Ref... |
343 |
struct tc3589x_platform_data *pdata = dev_get_platdata(&i2c->dev); |
20406ebff mfd/tc3589x: rena... |
344 |
struct tc3589x *tc3589x; |
a381b13e2 mfd: tc3589x: Ref... |
345 |
enum tc3589x_version version; |
b4ecd326b mfd: Add Toshiba'... |
346 |
int ret; |
a435ae1d5 mfd: Enable the t... |
347 |
if (!pdata) { |
a381b13e2 mfd: tc3589x: Ref... |
348 349 |
pdata = tc3589x_of_probe(&i2c->dev, &version); if (IS_ERR(pdata)) { |
a435ae1d5 mfd: Enable the t... |
350 351 |
dev_err(&i2c->dev, "No platform data or DT found "); |
a381b13e2 mfd: tc3589x: Ref... |
352 |
return PTR_ERR(pdata); |
a435ae1d5 mfd: Enable the t... |
353 |
} |
a381b13e2 mfd: tc3589x: Ref... |
354 355 356 |
} else { /* When not probing from device tree we have this ID */ version = id->driver_data; |
a435ae1d5 mfd: Enable the t... |
357 |
} |
b4ecd326b mfd: Add Toshiba'... |
358 359 360 |
if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_I2C_BLOCK)) return -EIO; |
1383e00f7 mfd: tc3589x: Use... |
361 362 |
tc3589x = devm_kzalloc(&i2c->dev, sizeof(struct tc3589x), GFP_KERNEL); |
20406ebff mfd/tc3589x: rena... |
363 |
if (!tc3589x) |
b4ecd326b mfd: Add Toshiba'... |
364 |
return -ENOMEM; |
20406ebff mfd/tc3589x: rena... |
365 |
mutex_init(&tc3589x->lock); |
b4ecd326b mfd: Add Toshiba'... |
366 |
|
20406ebff mfd/tc3589x: rena... |
367 368 369 |
tc3589x->dev = &i2c->dev; tc3589x->i2c = i2c; tc3589x->pdata = pdata; |
e64c1eb47 mfd: tc3589x: Det... |
370 |
|
a381b13e2 mfd: tc3589x: Ref... |
371 |
switch (version) { |
e64c1eb47 mfd: tc3589x: Det... |
372 373 374 375 376 377 378 379 380 381 382 383 384 |
case TC3589X_TC35893: case TC3589X_TC35895: case TC3589X_TC35896: tc3589x->num_gpio = 20; break; case TC3589X_TC35890: case TC3589X_TC35892: case TC3589X_TC35894: case TC3589X_UNKNOWN: default: tc3589x->num_gpio = 24; break; } |
b4ecd326b mfd: Add Toshiba'... |
385 |
|
20406ebff mfd/tc3589x: rena... |
386 |
i2c_set_clientdata(i2c, tc3589x); |
b4ecd326b mfd: Add Toshiba'... |
387 |
|
20406ebff mfd/tc3589x: rena... |
388 |
ret = tc3589x_chip_init(tc3589x); |
b4ecd326b mfd: Add Toshiba'... |
389 |
if (ret) |
1383e00f7 mfd: tc3589x: Use... |
390 |
return ret; |
b4ecd326b mfd: Add Toshiba'... |
391 |
|
a435ae1d5 mfd: Enable the t... |
392 |
ret = tc3589x_irq_init(tc3589x, np); |
b4ecd326b mfd: Add Toshiba'... |
393 |
if (ret) |
1383e00f7 mfd: tc3589x: Use... |
394 |
return ret; |
b4ecd326b mfd: Add Toshiba'... |
395 |
|
20406ebff mfd/tc3589x: rena... |
396 |
ret = request_threaded_irq(tc3589x->i2c->irq, NULL, tc3589x_irq, |
b4ecd326b mfd: Add Toshiba'... |
397 |
IRQF_TRIGGER_FALLING | IRQF_ONESHOT, |
20406ebff mfd/tc3589x: rena... |
398 |
"tc3589x", tc3589x); |
b4ecd326b mfd: Add Toshiba'... |
399 |
if (ret) { |
20406ebff mfd/tc3589x: rena... |
400 401 |
dev_err(tc3589x->dev, "failed to request IRQ: %d ", ret); |
1383e00f7 mfd: tc3589x: Use... |
402 |
return ret; |
b4ecd326b mfd: Add Toshiba'... |
403 |
} |
611b7590a mfd/tc3589x: add ... |
404 |
ret = tc3589x_device_init(tc3589x); |
b4ecd326b mfd: Add Toshiba'... |
405 |
if (ret) { |
611b7590a mfd/tc3589x: add ... |
406 407 |
dev_err(tc3589x->dev, "failed to add child devices "); |
1383e00f7 mfd: tc3589x: Use... |
408 |
return ret; |
b4ecd326b mfd: Add Toshiba'... |
409 410 411 |
} return 0; |
b4ecd326b mfd: Add Toshiba'... |
412 |
} |
4740f73fe mfd: remove use o... |
413 |
static int tc3589x_remove(struct i2c_client *client) |
b4ecd326b mfd: Add Toshiba'... |
414 |
{ |
20406ebff mfd/tc3589x: rena... |
415 |
struct tc3589x *tc3589x = i2c_get_clientdata(client); |
b4ecd326b mfd: Add Toshiba'... |
416 |
|
20406ebff mfd/tc3589x: rena... |
417 |
mfd_remove_devices(tc3589x->dev); |
b4ecd326b mfd: Add Toshiba'... |
418 |
|
b4ecd326b mfd: Add Toshiba'... |
419 420 |
return 0; } |
930bf0229 mfd: Guard tc3589... |
421 |
#ifdef CONFIG_PM_SLEEP |
593e9d70f mfd/tc3589x: add ... |
422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 |
static int tc3589x_suspend(struct device *dev) { struct tc3589x *tc3589x = dev_get_drvdata(dev); struct i2c_client *client = tc3589x->i2c; int ret = 0; /* put the system to sleep mode */ if (!device_may_wakeup(&client->dev)) ret = tc3589x_reg_write(tc3589x, TC3589x_CLKMODE, TC3589x_CLKMODE_MODCTL_SLEEP); return ret; } static int tc3589x_resume(struct device *dev) { struct tc3589x *tc3589x = dev_get_drvdata(dev); struct i2c_client *client = tc3589x->i2c; int ret = 0; /* enable the system into operation */ if (!device_may_wakeup(&client->dev)) ret = tc3589x_reg_write(tc3589x, TC3589x_CLKMODE, TC3589x_CLKMODE_MODCTL_OPERATION); return ret; } |
54d8e2c32 mfd: Add missing ... |
449 |
#endif |
593e9d70f mfd/tc3589x: add ... |
450 |
|
930bf0229 mfd: Guard tc3589... |
451 |
static SIMPLE_DEV_PM_OPS(tc3589x_dev_pm_ops, tc3589x_suspend, tc3589x_resume); |
20406ebff mfd/tc3589x: rena... |
452 |
static const struct i2c_device_id tc3589x_id[] = { |
e64c1eb47 mfd: tc3589x: Det... |
453 454 455 456 457 458 459 |
{ "tc35890", TC3589X_TC35890 }, { "tc35892", TC3589X_TC35892 }, { "tc35893", TC3589X_TC35893 }, { "tc35894", TC3589X_TC35894 }, { "tc35895", TC3589X_TC35895 }, { "tc35896", TC3589X_TC35896 }, { "tc3589x", TC3589X_UNKNOWN }, |
b4ecd326b mfd: Add Toshiba'... |
460 461 |
{ } }; |
20406ebff mfd/tc3589x: rena... |
462 |
MODULE_DEVICE_TABLE(i2c, tc3589x_id); |
b4ecd326b mfd: Add Toshiba'... |
463 |
|
20406ebff mfd/tc3589x: rena... |
464 |
static struct i2c_driver tc3589x_driver = { |
a381b13e2 mfd: tc3589x: Ref... |
465 466 |
.driver = { .name = "tc3589x", |
a381b13e2 mfd: tc3589x: Ref... |
467 468 469 |
.pm = &tc3589x_dev_pm_ops, .of_match_table = of_match_ptr(tc3589x_match), }, |
20406ebff mfd/tc3589x: rena... |
470 |
.probe = tc3589x_probe, |
84449216b mfd: remove use o... |
471 |
.remove = tc3589x_remove, |
20406ebff mfd/tc3589x: rena... |
472 |
.id_table = tc3589x_id, |
b4ecd326b mfd: Add Toshiba'... |
473 |
}; |
20406ebff mfd/tc3589x: rena... |
474 |
static int __init tc3589x_init(void) |
b4ecd326b mfd: Add Toshiba'... |
475 |
{ |
20406ebff mfd/tc3589x: rena... |
476 |
return i2c_add_driver(&tc3589x_driver); |
b4ecd326b mfd: Add Toshiba'... |
477 |
} |
20406ebff mfd/tc3589x: rena... |
478 |
subsys_initcall(tc3589x_init); |
b4ecd326b mfd: Add Toshiba'... |
479 |
|
20406ebff mfd/tc3589x: rena... |
480 |
static void __exit tc3589x_exit(void) |
b4ecd326b mfd: Add Toshiba'... |
481 |
{ |
20406ebff mfd/tc3589x: rena... |
482 |
i2c_del_driver(&tc3589x_driver); |
b4ecd326b mfd: Add Toshiba'... |
483 |
} |
20406ebff mfd/tc3589x: rena... |
484 |
module_exit(tc3589x_exit); |
b4ecd326b mfd: Add Toshiba'... |
485 486 |
MODULE_LICENSE("GPL v2"); |
20406ebff mfd/tc3589x: rena... |
487 |
MODULE_DESCRIPTION("TC3589x MFD core driver"); |
b4ecd326b mfd: Add Toshiba'... |
488 |
MODULE_AUTHOR("Hanumath Prasad, Rabin Vincent"); |