blob: d3304eb37106f7d5e38b0de552cd354e2ee8d932 [file] [log] [blame]
Vijayavardhan Vennapusaafbbb8f2012-04-13 16:28:45 +05301/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 */
12
13#include <linux/platform_device.h>
14#include <linux/err.h>
15#include <linux/pm_runtime.h>
16#include <linux/regulator/consumer.h>
17#include <linux/i2c.h>
18#include <linux/gpio.h>
19#include <linux/slab.h>
20#include <linux/delay.h>
21#include <linux/smsc3503.h>
22#include <mach/msm_xo.h>
23
24#define SMSC3503_I2C_ADDR 0x08
25#define SMSC_GSBI_I2C_BUS_ID 10
26static const unsigned short normal_i2c[] = {
27SMSC3503_I2C_ADDR, I2C_CLIENT_END };
28
29struct hsic_hub {
30 struct regulator *hsic_hub_reg;
31 struct device *dev;
32 struct i2c_client *client;
33 struct msm_xo_voter *xo_handle;
34};
35static struct hsic_hub *smsc_hub;
36
37/* APIs for setting/clearing bits and for reading/writing values */
38static inline int hsic_hub_get_u8(struct i2c_client *client, u8 reg)
39{
40 int ret;
41
42 ret = i2c_smbus_read_byte_data(client, reg);
43 if (ret < 0)
44 pr_err("%s:i2c_read8 failed\n", __func__);
45 return ret;
46}
47
48static inline int hsic_hub_get_u16(struct i2c_client *client, u8 reg)
49{
50 int ret;
51
52 ret = i2c_smbus_read_word_data(client, reg);
53 if (ret < 0)
54 pr_err("%s:i2c_read16 failed\n", __func__);
55 return ret;
56}
57
58static inline int hsic_hub_write_word_data(struct i2c_client *client, u8 reg,
59 u16 value)
60{
61 int ret;
62
63 ret = i2c_smbus_write_word_data(client, reg, value);
64 if (ret)
65 pr_err("%s:i2c_write16 failed\n", __func__);
66 return ret;
67}
68
69static inline int hsic_hub_write_byte_data(struct i2c_client *client, u8 reg,
70 u8 value)
71{
72 int ret;
73
74 ret = i2c_smbus_write_byte_data(client, reg, value);
75 if (ret)
76 pr_err("%s:i2c_write_byte_data failed\n", __func__);
77 return ret;
78}
79
80static inline int hsic_hub_set_bits(struct i2c_client *client, u8 reg,
81 u8 value)
82{
83 int ret;
84
85 ret = i2c_smbus_read_byte_data(client, reg);
86 if (ret < 0) {
87 pr_err("%s:i2c_read_byte_data failed\n", __func__);
88 return ret;
89 }
90 return i2c_smbus_write_byte_data(client, reg, (ret | value));
91}
92
93static inline int hsic_hub_clear_bits(struct i2c_client *client, u8 reg,
94 u8 value)
95{
96 int ret;
97
98 ret = i2c_smbus_read_byte_data(client, reg);
99 if (ret < 0) {
100 pr_err("%s:i2c_read_byte_data failed\n", __func__);
101 return ret;
102 }
103 return i2c_smbus_write_byte_data(client, reg, (ret & ~value));
104}
105
106static int i2c_hsic_hub_probe(struct i2c_client *client,
107 const struct i2c_device_id *id)
108{
109 if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA |
110 I2C_FUNC_SMBUS_WORD_DATA))
111 return -EIO;
112
113 return 0;
114}
115
116static int i2c_hsic_hub_remove(struct i2c_client *client)
117{
118 return 0;
119}
120
121static const struct i2c_device_id hsic_hub_id[] = {
122 {"i2c_hsic_hub", 0},
123 {}
124};
125MODULE_DEVICE_TABLE(i2c, hsichub_id);
126
127static struct i2c_driver hsic_hub_driver = {
128 .driver = {
129 .name = "i2c_hsic_hub",
130 },
131 .probe = i2c_hsic_hub_probe,
132 .remove = i2c_hsic_hub_remove,
133 .id_table = hsic_hub_id,
134};
135
136#define HSIC_HUB_VDD_VOL_MIN 1650000 /* uV */
137#define HSIC_HUB_VDD_VOL_MAX 1950000 /* uV */
138#define HSIC_HUB_VDD_LOAD 36000 /* uA */
139static int __devinit smsc_hub_probe(struct platform_device *pdev)
140{
141 int ret = 0;
142 const struct smsc_hub_platform_data *pdata;
143 struct i2c_adapter *i2c_adap;
144 struct i2c_board_info i2c_info;
145
146 if (!pdev->dev.platform_data) {
147 dev_err(&pdev->dev, "No platform data\n");
148 return -ENODEV;
149 }
150
151 pdata = pdev->dev.platform_data;
152 if (!pdata->hub_reset)
153 return -EINVAL;
154
155 smsc_hub = kzalloc(sizeof(*smsc_hub), GFP_KERNEL);
156 if (!smsc_hub)
157 return -ENOMEM;
158
159 smsc_hub->hsic_hub_reg = regulator_get(&pdev->dev, "EXT_HUB_VDDIO");
160 if (IS_ERR(smsc_hub->hsic_hub_reg)) {
161 dev_err(&pdev->dev, "unable to get ext hub vddcx\n");
162 ret = PTR_ERR(smsc_hub->hsic_hub_reg);
163 goto free_mem;
164 }
165
166 ret = gpio_request(pdata->hub_reset, "HSIC_HUB_RESET_GPIO");
167 if (ret < 0) {
168 dev_err(&pdev->dev, "gpio request failed for GPIO%d\n",
169 pdata->hub_reset);
170 goto gpio_req_fail;
171 }
172
173 ret = regulator_set_voltage(smsc_hub->hsic_hub_reg,
174 HSIC_HUB_VDD_VOL_MIN,
175 HSIC_HUB_VDD_VOL_MAX);
176 if (ret) {
177 dev_err(&pdev->dev, "unable to set the voltage"
178 "for hsic hub reg\n");
179 goto reg_set_voltage_fail;
180 }
181
182 ret = regulator_set_optimum_mode(smsc_hub->hsic_hub_reg,
183 HSIC_HUB_VDD_LOAD);
184 if (ret < 0) {
185 dev_err(&pdev->dev, "Unable to set optimum mode of regulator:"
186 "VDDCX\n");
187 goto reg_optimum_mode_fail;
188 }
189
190 ret = regulator_enable(smsc_hub->hsic_hub_reg);
191 if (ret) {
192 dev_err(&pdev->dev, "unable to enable ext hub vddcx\n");
193 goto reg_enable_fail;
194 }
195
196 smsc_hub->xo_handle = msm_xo_get(MSM_XO_TCXO_D1, "hsic_hub");
197 if (IS_ERR(smsc_hub->xo_handle)) {
198 dev_err(&pdev->dev, "not able to get the handle"
199 "for TCXO D1 buffer\n");
200 goto disable_regulator;
201 }
202
203 ret = msm_xo_mode_vote(smsc_hub->xo_handle, MSM_XO_MODE_ON);
204 if (ret) {
205 dev_err(&pdev->dev, "failed to vote for TCXO"
206 "D1 buffer\n");
207 goto xo_vote_fail;
208 }
209
210 gpio_direction_output(pdata->hub_reset, 0);
211 /* Hub reset should be asserted for minimum 2microsec
212 * before deasserting.
213 */
214 udelay(5);
215 gpio_direction_output(pdata->hub_reset, 1);
216
217 ret = i2c_add_driver(&hsic_hub_driver);
218 if (ret < 0) {
219 dev_err(&pdev->dev, "failed to add I2C hsic_hub_driver\n");
220 goto i2c_add_fail;
221 }
222 usleep_range(10000, 12000);
223 i2c_adap = i2c_get_adapter(SMSC_GSBI_I2C_BUS_ID);
224
225 if (!i2c_adap) {
226 dev_err(&pdev->dev, "failed to get i2c adapter\n");
227 i2c_del_driver(&hsic_hub_driver);
228 goto i2c_add_fail;
229 }
230
231 memset(&i2c_info, 0, sizeof(struct i2c_board_info));
232 strlcpy(i2c_info.type, "i2c_hsic_hub", I2C_NAME_SIZE);
233
234 smsc_hub->client = i2c_new_probed_device(i2c_adap, &i2c_info,
235 normal_i2c, NULL);
236 i2c_put_adapter(i2c_adap);
237 if (!smsc_hub->client)
238 dev_err(&pdev->dev, "failed to connect to smsc_hub"
239 "through I2C\n");
240
241i2c_add_fail:
242 pm_runtime_set_active(&pdev->dev);
243 pm_runtime_enable(&pdev->dev);
244
245 return 0;
246
247xo_vote_fail:
248 msm_xo_put(smsc_hub->xo_handle);
249disable_regulator:
250 regulator_disable(smsc_hub->hsic_hub_reg);
251reg_enable_fail:
252 regulator_set_optimum_mode(smsc_hub->hsic_hub_reg, 0);
253reg_optimum_mode_fail:
254 regulator_set_voltage(smsc_hub->hsic_hub_reg, 0,
255 HSIC_HUB_VDD_VOL_MIN);
256reg_set_voltage_fail:
257 gpio_free(pdata->hub_reset);
258gpio_req_fail:
259 regulator_put(smsc_hub->hsic_hub_reg);
260free_mem:
261 kfree(smsc_hub);
262
263 return ret;
264}
265
266static int smsc_hub_remove(struct platform_device *pdev)
267{
268 const struct smsc_hub_platform_data *pdata;
269
270 pdata = pdev->dev.platform_data;
271 if (smsc_hub->client) {
272 i2c_unregister_device(smsc_hub->client);
273 smsc_hub->client = NULL;
274 i2c_del_driver(&hsic_hub_driver);
275 }
276 pm_runtime_disable(&pdev->dev);
277 msm_xo_put(smsc_hub->xo_handle);
278
279 regulator_disable(smsc_hub->hsic_hub_reg);
280 regulator_set_optimum_mode(smsc_hub->hsic_hub_reg, 0);
281 regulator_set_voltage(smsc_hub->hsic_hub_reg, 0,
282 HSIC_HUB_VDD_VOL_MIN);
283 gpio_free(pdata->hub_reset);
284 regulator_put(smsc_hub->hsic_hub_reg);
285 kfree(smsc_hub);
286
287 return 0;
288}
289
290#ifdef CONFIG_PM_RUNTIME
291static int msm_smsc_runtime_idle(struct device *dev)
292{
293 dev_dbg(dev, "SMSC HUB runtime idle\n");
294
295 return 0;
296}
297
298static int smsc_hub_lpm_enter(struct device *dev)
299{
300 int ret;
301
302 ret = msm_xo_mode_vote(smsc_hub->xo_handle, MSM_XO_MODE_OFF);
303 if (ret) {
304 pr_err("%s: failed to devote for TCXO"
305 "D1 buffer%d\n", __func__, ret);
306 }
307 return ret;
308}
309
310static int smsc_hub_lpm_exit(struct device *dev)
311{
312 int ret;
313
314 ret = msm_xo_mode_vote(smsc_hub->xo_handle, MSM_XO_MODE_ON);
315 if (ret) {
316 pr_err("%s: failed to vote for TCXO"
317 "D1 buffer%d\n", __func__, ret);
318 }
319 return ret;
320}
321#endif
322
323#ifdef CONFIG_PM
324static const struct dev_pm_ops smsc_hub_dev_pm_ops = {
325 SET_SYSTEM_SLEEP_PM_OPS(smsc_hub_lpm_enter, smsc_hub_lpm_exit)
326 SET_RUNTIME_PM_OPS(smsc_hub_lpm_enter, smsc_hub_lpm_exit,
327 msm_smsc_runtime_idle)
328};
329#endif
330
331static struct platform_driver smsc_hub_driver = {
332 .driver = {
333 .name = "msm_smsc_hub",
334 .owner = THIS_MODULE,
335#ifdef CONFIG_PM
336 .pm = &smsc_hub_dev_pm_ops,
337#endif
338 },
339 .remove = smsc_hub_remove,
340};
341
342static int __init smsc_hub_init(void)
343{
344 return platform_driver_probe(&smsc_hub_driver, smsc_hub_probe);
345}
346
347static void __exit smsc_hub_exit(void)
348{
349 platform_driver_unregister(&smsc_hub_driver);
350}
351subsys_initcall(smsc_hub_init);
352module_exit(smsc_hub_exit);
353
354MODULE_LICENSE("GPL v2");
355MODULE_DESCRIPTION("SMSC HSIC HUB driver");