Commit | Line | Data |
---|---|---|
1a6e4b74 VK |
1 | /* |
2 | * ST Microelectronics MFD: stmpe's i2c client specific driver | |
3 | * | |
4 | * Copyright (C) ST-Ericsson SA 2010 | |
5 | * Copyright (C) ST Microelectronics SA 2011 | |
6 | * | |
7 | * License Terms: GNU General Public License, version 2 | |
8 | * Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson | |
da89947b | 9 | * Author: Viresh Kumar <vireshk@kernel.org> for ST Microelectronics |
1a6e4b74 VK |
10 | */ |
11 | ||
12 | #include <linux/i2c.h> | |
13 | #include <linux/interrupt.h> | |
14 | #include <linux/kernel.h> | |
15 | #include <linux/module.h> | |
16 | #include <linux/types.h> | |
5a826fee | 17 | #include <linux/of_device.h> |
1a6e4b74 VK |
18 | #include "stmpe.h" |
19 | ||
20 | static int i2c_reg_read(struct stmpe *stmpe, u8 reg) | |
21 | { | |
22 | struct i2c_client *i2c = stmpe->client; | |
23 | ||
24 | return i2c_smbus_read_byte_data(i2c, reg); | |
25 | } | |
26 | ||
27 | static int i2c_reg_write(struct stmpe *stmpe, u8 reg, u8 val) | |
28 | { | |
29 | struct i2c_client *i2c = stmpe->client; | |
30 | ||
31 | return i2c_smbus_write_byte_data(i2c, reg, val); | |
32 | } | |
33 | ||
34 | static int i2c_block_read(struct stmpe *stmpe, u8 reg, u8 length, u8 *values) | |
35 | { | |
36 | struct i2c_client *i2c = stmpe->client; | |
37 | ||
38 | return i2c_smbus_read_i2c_block_data(i2c, reg, length, values); | |
39 | } | |
40 | ||
41 | static int i2c_block_write(struct stmpe *stmpe, u8 reg, u8 length, | |
42 | const u8 *values) | |
43 | { | |
44 | struct i2c_client *i2c = stmpe->client; | |
45 | ||
46 | return i2c_smbus_write_i2c_block_data(i2c, reg, length, values); | |
47 | } | |
48 | ||
49 | static struct stmpe_client_info i2c_ci = { | |
50 | .read_byte = i2c_reg_read, | |
51 | .write_byte = i2c_reg_write, | |
52 | .read_block = i2c_block_read, | |
53 | .write_block = i2c_block_write, | |
54 | }; | |
55 | ||
5a826fee LW |
56 | static const struct of_device_id stmpe_of_match[] = { |
57 | { .compatible = "st,stmpe610", .data = (void *)STMPE610, }, | |
58 | { .compatible = "st,stmpe801", .data = (void *)STMPE801, }, | |
59 | { .compatible = "st,stmpe811", .data = (void *)STMPE811, }, | |
60 | { .compatible = "st,stmpe1601", .data = (void *)STMPE1601, }, | |
61 | { .compatible = "st,stmpe1801", .data = (void *)STMPE1801, }, | |
62 | { .compatible = "st,stmpe2401", .data = (void *)STMPE2401, }, | |
63 | { .compatible = "st,stmpe2403", .data = (void *)STMPE2403, }, | |
64 | {}, | |
65 | }; | |
66 | MODULE_DEVICE_TABLE(of, stmpe_of_match); | |
67 | ||
f791be49 | 68 | static int |
1a6e4b74 VK |
69 | stmpe_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) |
70 | { | |
c00572bc | 71 | enum stmpe_partnum partnum; |
5a826fee LW |
72 | const struct of_device_id *of_id; |
73 | ||
1a6e4b74 VK |
74 | i2c_ci.data = (void *)id; |
75 | i2c_ci.irq = i2c->irq; | |
76 | i2c_ci.client = i2c; | |
77 | i2c_ci.dev = &i2c->dev; | |
78 | ||
5a826fee LW |
79 | of_id = of_match_device(stmpe_of_match, &i2c->dev); |
80 | if (!of_id) { | |
81 | /* | |
82 | * This happens when the I2C ID matches the node name | |
83 | * but no real compatible string has been given. | |
84 | */ | |
85 | dev_info(&i2c->dev, "matching on node name, compatible is preferred\n"); | |
86 | partnum = id->driver_data; | |
87 | } else | |
c00572bc | 88 | partnum = (enum stmpe_partnum)of_id->data; |
5a826fee LW |
89 | |
90 | return stmpe_probe(&i2c_ci, partnum); | |
1a6e4b74 VK |
91 | } |
92 | ||
4740f73f | 93 | static int stmpe_i2c_remove(struct i2c_client *i2c) |
1a6e4b74 VK |
94 | { |
95 | struct stmpe *stmpe = dev_get_drvdata(&i2c->dev); | |
96 | ||
97 | return stmpe_remove(stmpe); | |
98 | } | |
99 | ||
100 | static const struct i2c_device_id stmpe_i2c_id[] = { | |
1cda2394 | 101 | { "stmpe610", STMPE610 }, |
7f7f4ea1 | 102 | { "stmpe801", STMPE801 }, |
1a6e4b74 VK |
103 | { "stmpe811", STMPE811 }, |
104 | { "stmpe1601", STMPE1601 }, | |
230f13a5 | 105 | { "stmpe1801", STMPE1801 }, |
1a6e4b74 VK |
106 | { "stmpe2401", STMPE2401 }, |
107 | { "stmpe2403", STMPE2403 }, | |
108 | { } | |
109 | }; | |
110 | MODULE_DEVICE_TABLE(i2c, stmpe_id); | |
111 | ||
112 | static struct i2c_driver stmpe_i2c_driver = { | |
32533983 VK |
113 | .driver = { |
114 | .name = "stmpe-i2c", | |
115 | .owner = THIS_MODULE, | |
1a6e4b74 | 116 | #ifdef CONFIG_PM |
32533983 | 117 | .pm = &stmpe_dev_pm_ops, |
1a6e4b74 | 118 | #endif |
5a826fee | 119 | .of_match_table = stmpe_of_match, |
32533983 | 120 | }, |
1a6e4b74 | 121 | .probe = stmpe_i2c_probe, |
84449216 | 122 | .remove = stmpe_i2c_remove, |
1a6e4b74 VK |
123 | .id_table = stmpe_i2c_id, |
124 | }; | |
125 | ||
126 | static int __init stmpe_init(void) | |
127 | { | |
128 | return i2c_add_driver(&stmpe_i2c_driver); | |
129 | } | |
130 | subsys_initcall(stmpe_init); | |
131 | ||
132 | static void __exit stmpe_exit(void) | |
133 | { | |
134 | i2c_del_driver(&stmpe_i2c_driver); | |
135 | } | |
136 | module_exit(stmpe_exit); | |
137 | ||
138 | MODULE_LICENSE("GPL v2"); | |
139 | MODULE_DESCRIPTION("STMPE MFD I2C Interface Driver"); | |
140 | MODULE_AUTHOR("Rabin Vincent <rabin.vincent@stericsson.com>"); |