blob: c95f2819e5cd8fc991efc87073f51f6850271611 [file] [log] [blame]
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +05301/* Copyright (c) 2011-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/kernel.h>
14#include <linux/module.h>
Kiran Kandi725f8492012-08-06 13:45:16 -070015#include <linux/of_gpio.h>
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +053016#include <linux/slab.h>
17#include <linux/mfd/core.h>
18#include <linux/mfd/wcd9xxx/wcd9xxx-slimslave.h>
19#include <linux/mfd/wcd9xxx/core.h>
20#include <linux/mfd/wcd9xxx/pdata.h>
21#include <linux/mfd/wcd9xxx/wcd9xxx_registers.h>
22
23#include <linux/delay.h>
24#include <linux/gpio.h>
25#include <linux/debugfs.h>
26#include <linux/regulator/consumer.h>
27#include <linux/i2c.h>
28#include <sound/soc.h>
29
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +053030#define WCD9XXX_REGISTER_START_OFFSET 0x800
31#define WCD9XXX_SLIM_RW_MAX_TRIES 3
Joonwoo Park3c5b2df2012-08-28 15:36:55 -070032#define SLIMBUS_PRESENT_TIMEOUT 100
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +053033
34#define MAX_WCD9XXX_DEVICE 4
Asish Bhattacharya2b709d42011-11-15 10:39:23 +053035#define TABLA_I2C_MODE 0x03
36#define SITAR_I2C_MODE 0x01
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +053037
38struct wcd9xxx_i2c {
39 struct i2c_client *client;
40 struct i2c_msg xfer_msg[2];
41 struct mutex xfer_lock;
42 int mod_id;
43};
44
45struct wcd9xxx_i2c wcd9xxx_modules[MAX_WCD9XXX_DEVICE];
Venkat Sudhirdb7aa2b2012-05-15 15:06:14 -070046static int wcd9xxx_intf = -1;
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +053047
48static int wcd9xxx_read(struct wcd9xxx *wcd9xxx, unsigned short reg,
49 int bytes, void *dest, bool interface_reg)
50{
51 int ret;
52 u8 *buf = dest;
53
54 if (bytes <= 0) {
55 dev_err(wcd9xxx->dev, "Invalid byte read length %d\n", bytes);
56 return -EINVAL;
57 }
58
59 ret = wcd9xxx->read_dev(wcd9xxx, reg, bytes, dest, interface_reg);
60 if (ret < 0) {
61 dev_err(wcd9xxx->dev, "Codec read failed\n");
62 return ret;
63 } else
Kiran Kandi1e6371d2012-03-29 11:48:57 -070064 dev_dbg(wcd9xxx->dev, "Read 0x%02x from 0x%x\n",
65 *buf, reg);
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +053066
67 return 0;
68}
69int wcd9xxx_reg_read(struct wcd9xxx *wcd9xxx, unsigned short reg)
70{
71 u8 val;
72 int ret;
73
74 mutex_lock(&wcd9xxx->io_lock);
75 ret = wcd9xxx_read(wcd9xxx, reg, 1, &val, false);
76 mutex_unlock(&wcd9xxx->io_lock);
77
78 if (ret < 0)
79 return ret;
80 else
81 return val;
82}
83EXPORT_SYMBOL_GPL(wcd9xxx_reg_read);
84
85static int wcd9xxx_write(struct wcd9xxx *wcd9xxx, unsigned short reg,
86 int bytes, void *src, bool interface_reg)
87{
88 u8 *buf = src;
89
90 if (bytes <= 0) {
91 pr_err("%s: Error, invalid write length\n", __func__);
92 return -EINVAL;
93 }
94
Kiran Kandi1e6371d2012-03-29 11:48:57 -070095 dev_dbg(wcd9xxx->dev, "Write %02x to 0x%x\n",
96 *buf, reg);
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +053097
98 return wcd9xxx->write_dev(wcd9xxx, reg, bytes, src, interface_reg);
99}
100
101int wcd9xxx_reg_write(struct wcd9xxx *wcd9xxx, unsigned short reg,
102 u8 val)
103{
104 int ret;
105
106 mutex_lock(&wcd9xxx->io_lock);
107 ret = wcd9xxx_write(wcd9xxx, reg, 1, &val, false);
108 mutex_unlock(&wcd9xxx->io_lock);
109
110 return ret;
111}
112EXPORT_SYMBOL_GPL(wcd9xxx_reg_write);
113
114static u8 wcd9xxx_pgd_la;
115static u8 wcd9xxx_inf_la;
116
117int wcd9xxx_interface_reg_read(struct wcd9xxx *wcd9xxx, unsigned short reg)
118{
119 u8 val;
120 int ret;
121
122 mutex_lock(&wcd9xxx->io_lock);
123 ret = wcd9xxx_read(wcd9xxx, reg, 1, &val, true);
124 mutex_unlock(&wcd9xxx->io_lock);
125
126 if (ret < 0)
127 return ret;
128 else
129 return val;
130}
131EXPORT_SYMBOL_GPL(wcd9xxx_interface_reg_read);
132
133int wcd9xxx_interface_reg_write(struct wcd9xxx *wcd9xxx, unsigned short reg,
134 u8 val)
135{
136 int ret;
137
138 mutex_lock(&wcd9xxx->io_lock);
139 ret = wcd9xxx_write(wcd9xxx, reg, 1, &val, true);
140 mutex_unlock(&wcd9xxx->io_lock);
141
142 return ret;
143}
144EXPORT_SYMBOL_GPL(wcd9xxx_interface_reg_write);
145
146int wcd9xxx_bulk_read(struct wcd9xxx *wcd9xxx, unsigned short reg,
147 int count, u8 *buf)
148{
149 int ret;
150
151 mutex_lock(&wcd9xxx->io_lock);
152
153 ret = wcd9xxx_read(wcd9xxx, reg, count, buf, false);
154
155 mutex_unlock(&wcd9xxx->io_lock);
156
157 return ret;
158}
159EXPORT_SYMBOL_GPL(wcd9xxx_bulk_read);
160
161int wcd9xxx_bulk_write(struct wcd9xxx *wcd9xxx, unsigned short reg,
162 int count, u8 *buf)
163{
164 int ret;
165
166 mutex_lock(&wcd9xxx->io_lock);
167
168 ret = wcd9xxx_write(wcd9xxx, reg, count, buf, false);
169
170 mutex_unlock(&wcd9xxx->io_lock);
171
172 return ret;
173}
174EXPORT_SYMBOL_GPL(wcd9xxx_bulk_write);
175
176static int wcd9xxx_slim_read_device(struct wcd9xxx *wcd9xxx, unsigned short reg,
177 int bytes, void *dest, bool interface)
178{
179 int ret;
180 struct slim_ele_access msg;
181 int slim_read_tries = WCD9XXX_SLIM_RW_MAX_TRIES;
182 msg.start_offset = WCD9XXX_REGISTER_START_OFFSET + reg;
183 msg.num_bytes = bytes;
184 msg.comp = NULL;
185
186 while (1) {
187 mutex_lock(&wcd9xxx->xfer_lock);
188 ret = slim_request_val_element(interface ?
189 wcd9xxx->slim_slave : wcd9xxx->slim,
190 &msg, dest, bytes);
191 mutex_unlock(&wcd9xxx->xfer_lock);
192 if (likely(ret == 0) || (--slim_read_tries == 0))
193 break;
194 usleep_range(5000, 5000);
195 }
196
197 if (ret)
198 pr_err("%s: Error, Codec read failed (%d)\n", __func__, ret);
199
200 return ret;
201}
202/* Interface specifies whether the write is to the interface or general
203 * registers.
204 */
205static int wcd9xxx_slim_write_device(struct wcd9xxx *wcd9xxx,
206 unsigned short reg, int bytes, void *src, bool interface)
207{
208 int ret;
209 struct slim_ele_access msg;
210 int slim_write_tries = WCD9XXX_SLIM_RW_MAX_TRIES;
211 msg.start_offset = WCD9XXX_REGISTER_START_OFFSET + reg;
212 msg.num_bytes = bytes;
213 msg.comp = NULL;
214
215 while (1) {
216 mutex_lock(&wcd9xxx->xfer_lock);
217 ret = slim_change_val_element(interface ?
218 wcd9xxx->slim_slave : wcd9xxx->slim,
219 &msg, src, bytes);
220 mutex_unlock(&wcd9xxx->xfer_lock);
221 if (likely(ret == 0) || (--slim_write_tries == 0))
222 break;
223 usleep_range(5000, 5000);
224 }
225
226 if (ret)
227 pr_err("%s: Error, Codec write failed (%d)\n", __func__, ret);
228
229 return ret;
230}
231
232static struct mfd_cell tabla1x_devs[] = {
233 {
234 .name = "tabla1x_codec",
235 },
236};
237
238static struct mfd_cell tabla_devs[] = {
239 {
240 .name = "tabla_codec",
241 },
242};
243
Asish Bhattacharyab86c3472012-02-15 08:31:52 +0530244static struct mfd_cell sitar_devs[] = {
245 {
246 .name = "sitar_codec",
247 },
248};
249
Joonwoo Parka7172112012-07-23 16:03:49 -0700250static struct mfd_cell taiko_devs[] = {
251 {
252 .name = "taiko_codec",
253 },
254};
255
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530256static void wcd9xxx_bring_up(struct wcd9xxx *wcd9xxx)
257{
258 wcd9xxx_reg_write(wcd9xxx, WCD9XXX_A_LEAKAGE_CTL, 0x4);
259 wcd9xxx_reg_write(wcd9xxx, WCD9XXX_A_CDC_CTL, 0);
260 usleep_range(5000, 5000);
261 wcd9xxx_reg_write(wcd9xxx, WCD9XXX_A_CDC_CTL, 3);
262 wcd9xxx_reg_write(wcd9xxx, WCD9XXX_A_LEAKAGE_CTL, 3);
263}
264
265static void wcd9xxx_bring_down(struct wcd9xxx *wcd9xxx)
266{
267 wcd9xxx_reg_write(wcd9xxx, WCD9XXX_A_LEAKAGE_CTL, 0x7);
268 wcd9xxx_reg_write(wcd9xxx, WCD9XXX_A_LEAKAGE_CTL, 0x6);
269 wcd9xxx_reg_write(wcd9xxx, WCD9XXX_A_LEAKAGE_CTL, 0xe);
270 wcd9xxx_reg_write(wcd9xxx, WCD9XXX_A_LEAKAGE_CTL, 0x8);
271}
272
273static int wcd9xxx_reset(struct wcd9xxx *wcd9xxx)
274{
275 int ret;
276
277 if (wcd9xxx->reset_gpio) {
278 ret = gpio_request(wcd9xxx->reset_gpio, "CDC_RESET");
279 if (ret) {
280 pr_err("%s: Failed to request gpio %d\n", __func__,
281 wcd9xxx->reset_gpio);
282 wcd9xxx->reset_gpio = 0;
283 return ret;
284 }
285
286 gpio_direction_output(wcd9xxx->reset_gpio, 1);
287 msleep(20);
288 gpio_direction_output(wcd9xxx->reset_gpio, 0);
289 msleep(20);
290 gpio_direction_output(wcd9xxx->reset_gpio, 1);
291 msleep(20);
292 }
293 return 0;
294}
295
296static void wcd9xxx_free_reset(struct wcd9xxx *wcd9xxx)
297{
298 if (wcd9xxx->reset_gpio) {
299 gpio_free(wcd9xxx->reset_gpio);
300 wcd9xxx->reset_gpio = 0;
301 }
302}
303
304static int wcd9xxx_device_init(struct wcd9xxx *wcd9xxx, int irq)
305{
306 int ret;
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530307 struct mfd_cell *wcd9xxx_dev = NULL;
308 int wcd9xxx_dev_size = 0;
309
310 mutex_init(&wcd9xxx->io_lock);
311 mutex_init(&wcd9xxx->xfer_lock);
312
313 mutex_init(&wcd9xxx->pm_lock);
314 wcd9xxx->wlock_holders = 0;
315 wcd9xxx->pm_state = WCD9XXX_PM_SLEEPABLE;
316 init_waitqueue_head(&wcd9xxx->pm_wq);
Stephen Boyd2fcabf92012-05-30 10:41:11 -0700317 pm_qos_add_request(&wcd9xxx->pm_qos_req, PM_QOS_CPU_DMA_LATENCY,
318 PM_QOS_DEFAULT_VALUE);
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530319
320 dev_set_drvdata(wcd9xxx->dev, wcd9xxx);
321
322 wcd9xxx_bring_up(wcd9xxx);
323
Kiran Kandi725f8492012-08-06 13:45:16 -0700324 if (wcd9xxx->irq != -1) {
325 ret = wcd9xxx_irq_init(wcd9xxx);
326 if (ret) {
327 pr_err("IRQ initialization failed\n");
328 goto err;
329 }
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530330 }
331
Asish Bhattacharya6dd4cb52012-07-05 19:47:42 +0530332 wcd9xxx->idbyte_0 = wcd9xxx_reg_read(wcd9xxx, WCD9XXX_A_CHIP_ID_BYTE_0);
333 wcd9xxx->idbyte_1 = wcd9xxx_reg_read(wcd9xxx, WCD9XXX_A_CHIP_ID_BYTE_1);
334 wcd9xxx->idbyte_2 = wcd9xxx_reg_read(wcd9xxx, WCD9XXX_A_CHIP_ID_BYTE_2);
335 wcd9xxx->idbyte_3 = wcd9xxx_reg_read(wcd9xxx, WCD9XXX_A_CHIP_ID_BYTE_3);
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530336
337 wcd9xxx->version = wcd9xxx_reg_read(wcd9xxx,
338 WCD9XXX_A_CHIP_VERSION) & 0x1F;
339 pr_info("%s : Codec version %u initialized\n",
340 __func__, wcd9xxx->version);
Asish Bhattacharyafbe371b2012-08-22 21:24:10 +0530341 pr_info("idbyte_0[%08x] idbyte_1[%08x] idbyte_2[%08x] idbyte_3[%08x]\n",
342 wcd9xxx->idbyte_0, wcd9xxx->idbyte_1,
343 wcd9xxx->idbyte_2, wcd9xxx->idbyte_3);
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530344
Asish Bhattacharyafbe371b2012-08-22 21:24:10 +0530345 if (wcd9xxx->idbyte_0 == 0x2 && wcd9xxx->idbyte_1 == 0x0 &&
346 wcd9xxx->idbyte_2 == 0x0 && wcd9xxx->idbyte_3 == 0x1) {
Asish Bhattacharya6dd4cb52012-07-05 19:47:42 +0530347 wcd9xxx_dev = tabla_devs;
348 wcd9xxx_dev_size = ARRAY_SIZE(tabla_devs);
Asish Bhattacharyafbe371b2012-08-22 21:24:10 +0530349 } else if (wcd9xxx->idbyte_0 == 0x1 && wcd9xxx->idbyte_1 == 0x0 &&
350 wcd9xxx->idbyte_2 == 0x0 && wcd9xxx->idbyte_3 == 0x1) {
Asish Bhattacharya6dd4cb52012-07-05 19:47:42 +0530351 wcd9xxx_dev = tabla1x_devs;
352 wcd9xxx_dev_size = ARRAY_SIZE(tabla1x_devs);
Joonwoo Parka7172112012-07-23 16:03:49 -0700353 } else if (wcd9xxx->idbyte_0 == 0x0 && wcd9xxx->idbyte_1 == 0x0 &&
354 wcd9xxx->idbyte_2 == 0x2 && wcd9xxx->idbyte_3 == 0x1) {
355 wcd9xxx_dev = taiko_devs;
356 wcd9xxx_dev_size = ARRAY_SIZE(taiko_devs);
Asish Bhattacharyafbe371b2012-08-22 21:24:10 +0530357 } else if ((wcd9xxx->idbyte_0 == 0x0 && wcd9xxx->idbyte_1 == 0x0 &&
358 wcd9xxx->idbyte_2 == 0x0 && wcd9xxx->idbyte_3 == 0x1) ||
359 (wcd9xxx->idbyte_0 == 0x1 && wcd9xxx->idbyte_1 == 0x0 &&
360 wcd9xxx->idbyte_2 == 0x1 && wcd9xxx->idbyte_3 == 0x1)) {
Asish Bhattacharya6dd4cb52012-07-05 19:47:42 +0530361 wcd9xxx_dev = sitar_devs;
362 wcd9xxx_dev_size = ARRAY_SIZE(sitar_devs);
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530363 }
Joonwoo Parka7172112012-07-23 16:03:49 -0700364 ret = mfd_add_devices(wcd9xxx->dev, -1, wcd9xxx_dev, wcd9xxx_dev_size,
365 NULL, 0);
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530366 if (ret != 0) {
367 dev_err(wcd9xxx->dev, "Failed to add children: %d\n", ret);
368 goto err_irq;
369 }
370 return ret;
371err_irq:
372 wcd9xxx_irq_exit(wcd9xxx);
373err:
374 wcd9xxx_bring_down(wcd9xxx);
Stephen Boyd2fcabf92012-05-30 10:41:11 -0700375 pm_qos_remove_request(&wcd9xxx->pm_qos_req);
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530376 mutex_destroy(&wcd9xxx->pm_lock);
377 mutex_destroy(&wcd9xxx->io_lock);
378 mutex_destroy(&wcd9xxx->xfer_lock);
379 return ret;
380}
381
382static void wcd9xxx_device_exit(struct wcd9xxx *wcd9xxx)
383{
384 wcd9xxx_irq_exit(wcd9xxx);
385 wcd9xxx_bring_down(wcd9xxx);
386 wcd9xxx_free_reset(wcd9xxx);
387 mutex_destroy(&wcd9xxx->pm_lock);
Stephen Boyd2fcabf92012-05-30 10:41:11 -0700388 pm_qos_remove_request(&wcd9xxx->pm_qos_req);
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530389 mutex_destroy(&wcd9xxx->io_lock);
390 mutex_destroy(&wcd9xxx->xfer_lock);
Venkat Sudhirdb7aa2b2012-05-15 15:06:14 -0700391 if (wcd9xxx_intf == WCD9XXX_INTERFACE_TYPE_SLIMBUS)
392 slim_remove_device(wcd9xxx->slim_slave);
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530393 kfree(wcd9xxx);
394}
395
396
397#ifdef CONFIG_DEBUG_FS
398struct wcd9xxx *debugCodec;
399
400static struct dentry *debugfs_wcd9xxx_dent;
401static struct dentry *debugfs_peek;
402static struct dentry *debugfs_poke;
403
404static unsigned char read_data;
405
406static int codec_debug_open(struct inode *inode, struct file *file)
407{
408 file->private_data = inode->i_private;
409 return 0;
410}
411
412static int get_parameters(char *buf, long int *param1, int num_of_par)
413{
414 char *token;
415 int base, cnt;
416
417 token = strsep(&buf, " ");
418
419 for (cnt = 0; cnt < num_of_par; cnt++) {
420 if (token != NULL) {
421 if ((token[1] == 'x') || (token[1] == 'X'))
422 base = 16;
423 else
424 base = 10;
425
426 if (strict_strtoul(token, base, &param1[cnt]) != 0)
427 return -EINVAL;
428
429 token = strsep(&buf, " ");
430 } else
431 return -EINVAL;
432 }
433 return 0;
434}
435
436static ssize_t codec_debug_read(struct file *file, char __user *ubuf,
437 size_t count, loff_t *ppos)
438{
439 char lbuf[8];
440
441 snprintf(lbuf, sizeof(lbuf), "0x%x\n", read_data);
442 return simple_read_from_buffer(ubuf, count, ppos, lbuf,
443 strnlen(lbuf, 7));
444}
445
446
447static ssize_t codec_debug_write(struct file *filp,
448 const char __user *ubuf, size_t cnt, loff_t *ppos)
449{
450 char *access_str = filp->private_data;
451 char lbuf[32];
452 int rc;
453 long int param[5];
454
455 if (cnt > sizeof(lbuf) - 1)
456 return -EINVAL;
457
458 rc = copy_from_user(lbuf, ubuf, cnt);
459 if (rc)
460 return -EFAULT;
461
462 lbuf[cnt] = '\0';
463
464 if (!strncmp(access_str, "poke", 6)) {
465 /* write */
466 rc = get_parameters(lbuf, param, 2);
467 if ((param[0] <= 0x3FF) && (param[1] <= 0xFF) &&
468 (rc == 0))
469 wcd9xxx_interface_reg_write(debugCodec, param[0],
470 param[1]);
471 else
472 rc = -EINVAL;
473 } else if (!strncmp(access_str, "peek", 6)) {
474 /* read */
475 rc = get_parameters(lbuf, param, 1);
476 if ((param[0] <= 0x3FF) && (rc == 0))
477 read_data = wcd9xxx_interface_reg_read(debugCodec,
478 param[0]);
479 else
480 rc = -EINVAL;
481 }
482
483 if (rc == 0)
484 rc = cnt;
485 else
486 pr_err("%s: rc = %d\n", __func__, rc);
487
488 return rc;
489}
490
491static const struct file_operations codec_debug_ops = {
492 .open = codec_debug_open,
493 .write = codec_debug_write,
494 .read = codec_debug_read
495};
496#endif
497
Venkat Sudhirdb7aa2b2012-05-15 15:06:14 -0700498static int wcd9xxx_enable_supplies(struct wcd9xxx *wcd9xxx,
499 struct wcd9xxx_pdata *pdata)
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530500{
501 int ret;
502 int i;
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530503 wcd9xxx->supplies = kzalloc(sizeof(struct regulator_bulk_data) *
504 ARRAY_SIZE(pdata->regulator),
505 GFP_KERNEL);
506 if (!wcd9xxx->supplies) {
507 ret = -ENOMEM;
508 goto err;
509 }
510
Kiran Kandi725f8492012-08-06 13:45:16 -0700511 wcd9xxx->num_of_supplies = 0;
512 for (i = 0; i < ARRAY_SIZE(pdata->regulator); i++) {
513 if (pdata->regulator[i].name) {
514 wcd9xxx->supplies[i].supply = pdata->regulator[i].name;
515 wcd9xxx->num_of_supplies++;
516 }
517 }
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530518
Kiran Kandi725f8492012-08-06 13:45:16 -0700519 ret = regulator_bulk_get(wcd9xxx->dev, wcd9xxx->num_of_supplies,
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530520 wcd9xxx->supplies);
521 if (ret != 0) {
522 dev_err(wcd9xxx->dev, "Failed to get supplies: err = %d\n",
523 ret);
524 goto err_supplies;
525 }
526
Kiran Kandi725f8492012-08-06 13:45:16 -0700527 for (i = 0; i < wcd9xxx->num_of_supplies; i++) {
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530528 ret = regulator_set_voltage(wcd9xxx->supplies[i].consumer,
529 pdata->regulator[i].min_uV, pdata->regulator[i].max_uV);
530 if (ret) {
531 pr_err("%s: Setting regulator voltage failed for "
532 "regulator %s err = %d\n", __func__,
533 wcd9xxx->supplies[i].supply, ret);
534 goto err_get;
535 }
536
537 ret = regulator_set_optimum_mode(wcd9xxx->supplies[i].consumer,
538 pdata->regulator[i].optimum_uA);
539 if (ret < 0) {
540 pr_err("%s: Setting regulator optimum mode failed for "
541 "regulator %s err = %d\n", __func__,
542 wcd9xxx->supplies[i].supply, ret);
543 goto err_get;
544 }
545 }
546
Kiran Kandi725f8492012-08-06 13:45:16 -0700547 ret = regulator_bulk_enable(wcd9xxx->num_of_supplies,
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530548 wcd9xxx->supplies);
549 if (ret != 0) {
550 dev_err(wcd9xxx->dev, "Failed to enable supplies: err = %d\n",
551 ret);
552 goto err_configure;
553 }
554 return ret;
555
556err_configure:
Kiran Kandi725f8492012-08-06 13:45:16 -0700557 for (i = 0; i < wcd9xxx->num_of_supplies; i++) {
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530558 regulator_set_voltage(wcd9xxx->supplies[i].consumer, 0,
559 pdata->regulator[i].max_uV);
560 regulator_set_optimum_mode(wcd9xxx->supplies[i].consumer, 0);
561 }
562err_get:
Kiran Kandi725f8492012-08-06 13:45:16 -0700563 regulator_bulk_free(wcd9xxx->num_of_supplies, wcd9xxx->supplies);
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530564err_supplies:
565 kfree(wcd9xxx->supplies);
566err:
567 return ret;
568}
569
Venkat Sudhir49203862012-05-21 14:29:13 -0700570static void wcd9xxx_disable_supplies(struct wcd9xxx *wcd9xxx,
571 struct wcd9xxx_pdata *pdata)
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530572{
573 int i;
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530574
Kiran Kandi725f8492012-08-06 13:45:16 -0700575 regulator_bulk_disable(wcd9xxx->num_of_supplies,
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530576 wcd9xxx->supplies);
Kiran Kandi725f8492012-08-06 13:45:16 -0700577 for (i = 0; i < wcd9xxx->num_of_supplies; i++) {
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530578 regulator_set_voltage(wcd9xxx->supplies[i].consumer, 0,
579 pdata->regulator[i].max_uV);
580 regulator_set_optimum_mode(wcd9xxx->supplies[i].consumer, 0);
581 }
Kiran Kandi725f8492012-08-06 13:45:16 -0700582 regulator_bulk_free(wcd9xxx->num_of_supplies, wcd9xxx->supplies);
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530583 kfree(wcd9xxx->supplies);
584}
585
586int wcd9xxx_get_intf_type(void)
587{
588 return wcd9xxx_intf;
589}
590EXPORT_SYMBOL_GPL(wcd9xxx_get_intf_type);
591
592struct wcd9xxx_i2c *get_i2c_wcd9xxx_device_info(u16 reg)
593{
594 u16 mask = 0x0f00;
595 int value = 0;
596 struct wcd9xxx_i2c *wcd9xxx = NULL;
597 value = ((reg & mask) >> 8) & 0x000f;
598 switch (value) {
599 case 0:
600 wcd9xxx = &wcd9xxx_modules[0];
601 break;
602 case 1:
603 wcd9xxx = &wcd9xxx_modules[1];
604 break;
605 case 2:
606 wcd9xxx = &wcd9xxx_modules[2];
607 break;
608 case 3:
609 wcd9xxx = &wcd9xxx_modules[3];
610 break;
611 default:
612 break;
613 }
614 return wcd9xxx;
615}
616
617int wcd9xxx_i2c_write_device(u16 reg, u8 *value,
618 u32 bytes)
619{
620
621 struct i2c_msg *msg;
622 int ret = 0;
623 u8 reg_addr = 0;
624 u8 data[bytes + 1];
625 struct wcd9xxx_i2c *wcd9xxx;
626
627 wcd9xxx = get_i2c_wcd9xxx_device_info(reg);
628 if (wcd9xxx == NULL || wcd9xxx->client == NULL) {
629 pr_err("failed to get device info\n");
630 return -ENODEV;
631 }
632 reg_addr = (u8)reg;
633 msg = &wcd9xxx->xfer_msg[0];
634 msg->addr = wcd9xxx->client->addr;
635 msg->len = bytes + 1;
636 msg->flags = 0;
637 data[0] = reg;
638 data[1] = *value;
639 msg->buf = data;
640 ret = i2c_transfer(wcd9xxx->client->adapter, wcd9xxx->xfer_msg, 1);
641 /* Try again if the write fails */
642 if (ret != 1) {
643 ret = i2c_transfer(wcd9xxx->client->adapter,
644 wcd9xxx->xfer_msg, 1);
645 if (ret != 1) {
646 pr_err("failed to write the device\n");
647 return ret;
648 }
649 }
650 pr_debug("write sucess register = %x val = %x\n", reg, data[1]);
651 return 0;
652}
653
654
655int wcd9xxx_i2c_read_device(unsigned short reg,
656 int bytes, unsigned char *dest)
657{
658 struct i2c_msg *msg;
659 int ret = 0;
660 u8 reg_addr = 0;
661 struct wcd9xxx_i2c *wcd9xxx;
662 u8 i = 0;
663
664 wcd9xxx = get_i2c_wcd9xxx_device_info(reg);
665 if (wcd9xxx == NULL || wcd9xxx->client == NULL) {
666 pr_err("failed to get device info\n");
667 return -ENODEV;
668 }
669 for (i = 0; i < bytes; i++) {
670 reg_addr = (u8)reg++;
671 msg = &wcd9xxx->xfer_msg[0];
672 msg->addr = wcd9xxx->client->addr;
673 msg->len = 1;
674 msg->flags = 0;
675 msg->buf = &reg_addr;
676
677 msg = &wcd9xxx->xfer_msg[1];
678 msg->addr = wcd9xxx->client->addr;
679 msg->len = 1;
680 msg->flags = I2C_M_RD;
681 msg->buf = dest++;
682 ret = i2c_transfer(wcd9xxx->client->adapter,
683 wcd9xxx->xfer_msg, 2);
684
685 /* Try again if read fails first time */
686 if (ret != 2) {
687 ret = i2c_transfer(wcd9xxx->client->adapter,
688 wcd9xxx->xfer_msg, 2);
689 if (ret != 2) {
690 pr_err("failed to read wcd9xxx register\n");
691 return ret;
692 }
693 }
694 }
695 return 0;
696}
697
698int wcd9xxx_i2c_read(struct wcd9xxx *wcd9xxx, unsigned short reg,
699 int bytes, void *dest, bool interface_reg)
700{
701 return wcd9xxx_i2c_read_device(reg, bytes, dest);
702}
703
704int wcd9xxx_i2c_write(struct wcd9xxx *wcd9xxx, unsigned short reg,
705 int bytes, void *src, bool interface_reg)
706{
707 return wcd9xxx_i2c_write_device(reg, src, bytes);
708}
709
710static int __devinit wcd9xxx_i2c_probe(struct i2c_client *client,
711 const struct i2c_device_id *id)
712{
713 struct wcd9xxx *wcd9xxx;
Venkat Sudhircbd522c2012-07-13 09:46:29 -0700714 struct wcd9xxx_pdata *pdata;
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530715 int val = 0;
716 int ret = 0;
Asish Bhattacharya2b709d42011-11-15 10:39:23 +0530717 int i2c_mode = 0;
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530718 static int device_id;
719
Asish Bhattacharya2b709d42011-11-15 10:39:23 +0530720 pr_info("%s\n", __func__);
Venkat Sudhirdb7aa2b2012-05-15 15:06:14 -0700721 if (wcd9xxx_intf == WCD9XXX_INTERFACE_TYPE_SLIMBUS) {
722 pr_info("tabla card is already detected in slimbus mode\n");
723 return -ENODEV;
724 }
Venkat Sudhircbd522c2012-07-13 09:46:29 -0700725 pdata = client->dev.platform_data;
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530726 if (device_id > 0) {
727 wcd9xxx_modules[device_id++].client = client;
728 pr_info("probe for other slaves devices of tabla\n");
729 return ret;
730 }
731
732 wcd9xxx = kzalloc(sizeof(struct wcd9xxx), GFP_KERNEL);
733 if (wcd9xxx == NULL) {
734 pr_err("%s: error, allocation failed\n", __func__);
735 ret = -ENOMEM;
736 goto fail;
737 }
738
739 if (!pdata) {
740 dev_dbg(&client->dev, "no platform data?\n");
741 ret = -EINVAL;
742 goto fail;
743 }
744 if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C) == 0) {
745 dev_dbg(&client->dev, "can't talk I2C?\n");
746 ret = -EIO;
747 goto fail;
748 }
Asish Bhattacharyab86c3472012-02-15 08:31:52 +0530749 dev_set_drvdata(&client->dev, wcd9xxx);
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530750 wcd9xxx->dev = &client->dev;
751 wcd9xxx->reset_gpio = pdata->reset_gpio;
Venkat Sudhirdb7aa2b2012-05-15 15:06:14 -0700752 ret = wcd9xxx_enable_supplies(wcd9xxx, pdata);
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530753 if (ret) {
754 pr_err("%s: Fail to enable Codec supplies\n", __func__);
755 goto err_codec;
756 }
757
758 usleep_range(5, 5);
759 ret = wcd9xxx_reset(wcd9xxx);
760 if (ret) {
761 pr_err("%s: Resetting Codec failed\n", __func__);
762 goto err_supplies;
763 }
764 wcd9xxx_modules[device_id++].client = client;
765
766 wcd9xxx->read_dev = wcd9xxx_i2c_read;
767 wcd9xxx->write_dev = wcd9xxx_i2c_write;
768 wcd9xxx->irq = pdata->irq;
769 wcd9xxx->irq_base = pdata->irq_base;
770
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530771 ret = wcd9xxx_device_init(wcd9xxx, wcd9xxx->irq);
772 if (ret) {
773 pr_err("%s: error, initializing device failed\n", __func__);
774 goto err_device_init;
775 }
Asish Bhattacharya6dd4cb52012-07-05 19:47:42 +0530776
777 if ((wcd9xxx->idbyte_0 == 0x2) || (wcd9xxx->idbyte_0 == 0x1))
778 i2c_mode = TABLA_I2C_MODE;
779 else if (wcd9xxx->idbyte_0 == 0x0)
780 i2c_mode = SITAR_I2C_MODE;
781
782 ret = wcd9xxx_read(wcd9xxx, WCD9XXX_A_CHIP_STATUS, 1, &val, 0);
783
784 if ((ret < 0) || (val != i2c_mode))
785 pr_err("failed to read the wcd9xxx status ret = %d\n", ret);
786
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530787 wcd9xxx_intf = WCD9XXX_INTERFACE_TYPE_I2C;
788
789 return ret;
790err_device_init:
791 wcd9xxx_free_reset(wcd9xxx);
792err_supplies:
Venkat Sudhir49203862012-05-21 14:29:13 -0700793 wcd9xxx_disable_supplies(wcd9xxx, pdata);
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530794err_codec:
795 kfree(wcd9xxx);
796fail:
797 return ret;
798}
799
800static int __devexit wcd9xxx_i2c_remove(struct i2c_client *client)
801{
802 struct wcd9xxx *wcd9xxx;
Venkat Sudhir49203862012-05-21 14:29:13 -0700803 struct wcd9xxx_pdata *pdata = client->dev.platform_data;
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530804 pr_debug("exit\n");
805 wcd9xxx = dev_get_drvdata(&client->dev);
Venkat Sudhir49203862012-05-21 14:29:13 -0700806 wcd9xxx_disable_supplies(wcd9xxx, pdata);
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530807 wcd9xxx_device_exit(wcd9xxx);
808 return 0;
809}
810
Kiran Kandi725f8492012-08-06 13:45:16 -0700811#define CODEC_DT_MAX_PROP_SIZE 40
812static int wcd9xxx_dt_parse_vreg_info(struct device *dev,
813 struct wcd9xxx_regulator *vreg, const char *vreg_name)
814{
815 int len, ret = 0;
816 const __be32 *prop;
817 char prop_name[CODEC_DT_MAX_PROP_SIZE];
818 struct device_node *regnode = NULL;
819 u32 prop_val;
820
821 snprintf(prop_name, CODEC_DT_MAX_PROP_SIZE, "%s-supply",
822 vreg_name);
823 regnode = of_parse_phandle(dev->of_node, prop_name, 0);
824
825 if (!regnode) {
826 dev_err(dev, "Looking up %s property in node %s failed",
827 prop_name, dev->of_node->full_name);
828 return -ENODEV;
829 }
830 vreg->name = vreg_name;
831
832 snprintf(prop_name, CODEC_DT_MAX_PROP_SIZE,
833 "qcom,%s-voltage", vreg_name);
834 prop = of_get_property(dev->of_node, prop_name, &len);
835
836 if (!prop || (len != (2 * sizeof(__be32)))) {
837 dev_err(dev, "%s %s property\n",
838 prop ? "invalid format" : "no", prop_name);
839 return -ENODEV;
840 } else {
841 vreg->min_uV = be32_to_cpup(&prop[0]);
842 vreg->max_uV = be32_to_cpup(&prop[1]);
843 }
844
845 snprintf(prop_name, CODEC_DT_MAX_PROP_SIZE,
846 "qcom,%s-current", vreg_name);
847
848 ret = of_property_read_u32(dev->of_node, prop_name, &prop_val);
849 if (ret) {
850 dev_err(dev, "Looking up %s property in node %s failed",
851 prop_name, dev->of_node->full_name);
852 return -ENODEV;
853 }
854 vreg->optimum_uA = prop_val;
855
856 dev_info(dev, "%s: vol=[%d %d]uV, curr=[%d]uA\n", vreg->name,
857 vreg->min_uV, vreg->max_uV, vreg->optimum_uA);
858 return 0;
859}
860
861static int wcd9xxx_dt_parse_micbias_info(struct device *dev,
862 struct wcd9xxx_micbias_setting *micbias)
863{
864 int ret = 0;
865 char prop_name[CODEC_DT_MAX_PROP_SIZE];
866 u32 prop_val;
867
868 snprintf(prop_name, CODEC_DT_MAX_PROP_SIZE,
869 "qcom,cdc-micbias-ldoh-v");
870 ret = of_property_read_u32(dev->of_node, prop_name, &prop_val);
871 if (ret) {
872 dev_err(dev, "Looking up %s property in node %s failed",
873 prop_name, dev->of_node->full_name);
874 return -ENODEV;
875 }
876 micbias->ldoh_v = (u8)prop_val;
877
878 snprintf(prop_name, CODEC_DT_MAX_PROP_SIZE,
879 "qcom,cdc-micbias-cfilt1-mv");
880 ret = of_property_read_u32(dev->of_node, prop_name,
881 &micbias->cfilt1_mv);
882 if (ret) {
883 dev_err(dev, "Looking up %s property in node %s failed",
884 prop_name, dev->of_node->full_name);
885 return -ENODEV;
886 }
887
888 snprintf(prop_name, CODEC_DT_MAX_PROP_SIZE,
889 "qcom,cdc-micbias-cfilt2-mv");
890 ret = of_property_read_u32(dev->of_node, prop_name,
891 &micbias->cfilt2_mv);
892 if (ret) {
893 dev_err(dev, "Looking up %s property in node %s failed",
894 prop_name, dev->of_node->full_name);
895 return -ENODEV;
896 }
897
898 snprintf(prop_name, CODEC_DT_MAX_PROP_SIZE,
899 "qcom,cdc-micbias-cfilt3-mv");
900 ret = of_property_read_u32(dev->of_node, prop_name,
901 &micbias->cfilt3_mv);
902 if (ret) {
903 dev_err(dev, "Looking up %s property in node %s failed",
904 prop_name, dev->of_node->full_name);
905 return -ENODEV;
906 }
907
908 snprintf(prop_name, CODEC_DT_MAX_PROP_SIZE,
909 "qcom,cdc-micbias1-cfilt-sel");
910 ret = of_property_read_u32(dev->of_node, prop_name, &prop_val);
911 if (ret) {
912 dev_err(dev, "Looking up %s property in node %s failed",
913 prop_name, dev->of_node->full_name);
914 return -ENODEV;
915 }
916 micbias->bias1_cfilt_sel = (u8)prop_val;
917
918 snprintf(prop_name, CODEC_DT_MAX_PROP_SIZE,
919 "qcom,cdc-micbias2-cfilt-sel");
920 ret = of_property_read_u32(dev->of_node, prop_name, &prop_val);
921 if (ret) {
922 dev_err(dev, "Looking up %s property in node %s failed",
923 prop_name, dev->of_node->full_name);
924 return -ENODEV;
925 }
926 micbias->bias2_cfilt_sel = (u8)prop_val;
927
928 snprintf(prop_name, CODEC_DT_MAX_PROP_SIZE,
929 "qcom,cdc-micbias3-cfilt-sel");
930 ret = of_property_read_u32(dev->of_node, prop_name, &prop_val);
931 if (ret) {
932 dev_err(dev, "Looking up %s property in node %s failed",
933 prop_name, dev->of_node->full_name);
934 return -ENODEV;
935 }
936 micbias->bias3_cfilt_sel = (u8)prop_val;
937
938 snprintf(prop_name, CODEC_DT_MAX_PROP_SIZE,
939 "qcom,cdc-micbias4-cfilt-sel");
940 ret = of_property_read_u32(dev->of_node, prop_name, &prop_val);
941 if (ret) {
942 dev_err(dev, "Looking up %s property in node %s failed",
943 prop_name, dev->of_node->full_name);
944 return -ENODEV;
945 }
946 micbias->bias4_cfilt_sel = (u8)prop_val;
947
948 dev_dbg(dev, "ldoh_v %u cfilt1_mv %u cfilt2_mv %u cfilt3_mv %u",
949 (u32)micbias->ldoh_v, (u32)micbias->cfilt1_mv,
950 (u32)micbias->cfilt2_mv, (u32)micbias->cfilt3_mv);
951
952 dev_dbg(dev, "bias1_cfilt_sel %u bias2_cfilt_sel %u\n",
953 (u32)micbias->bias1_cfilt_sel, (u32)micbias->bias2_cfilt_sel);
954
955 dev_dbg(dev, "bias3_cfilt_sel %u bias4_cfilt_sel %u\n",
956 (u32)micbias->bias3_cfilt_sel, (u32)micbias->bias4_cfilt_sel);
957
958 return 0;
959}
960
961static int wcd9xxx_dt_parse_slim_interface_dev_info(struct device *dev,
962 struct slim_device *slim_ifd)
963{
964 int ret = 0;
965 struct property *prop;
966
967 ret = of_property_read_string(dev->of_node, "qcom,cdc-slim-ifd",
968 &slim_ifd->name);
969 if (ret) {
970 dev_err(dev, "Looking up %s property in node %s failed",
971 "qcom,cdc-slim-ifd-dev", dev->of_node->full_name);
972 return -ENODEV;
973 }
974 prop = of_find_property(dev->of_node,
975 "qcom,cdc-slim-ifd-elemental-addr", NULL);
976 if (!prop) {
977 dev_err(dev, "Looking up %s property in node %s failed",
978 "qcom,cdc-slim-ifd-elemental-addr",
979 dev->of_node->full_name);
980 return -ENODEV;
981 } else if (prop->length != 6) {
982 dev_err(dev, "invalid codec slim ifd addr. addr length = %d\n",
983 prop->length);
984 return -ENODEV;
985 }
986 memcpy(slim_ifd->e_addr, prop->value, 6);
987
988 return 0;
989}
990
991static char *taiko_supplies[] = {
992 "cdc-vdd-buck", "cdc-vdd-tx-h", "cdc-vdd-rx-h", "cdc-vddpx-1",
993 "cdc-vdd-a-1p2v", "cdc-vddcx-1", "cdc-vddcx-2",
994};
995
996static struct wcd9xxx_pdata *wcd9xxx_populate_dt_pdata(struct device *dev)
997{
998 struct wcd9xxx_pdata *pdata;
999 int ret, i;
1000 char **codec_supplies;
1001 u32 num_of_supplies = 0;
1002
1003 pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
1004 if (!pdata) {
1005 dev_err(dev,
1006 "could not allocate memory for platform data\n");
1007 return NULL;
1008 }
1009
1010 if (!strcmp(dev_name(dev), "taiko-slim-pgd")) {
1011 codec_supplies = taiko_supplies;
1012 num_of_supplies = ARRAY_SIZE(taiko_supplies);
1013 } else {
1014 dev_err(dev, "%s unsupported device %s\n",
1015 __func__, dev_name(dev));
1016 goto err;
1017 }
1018
1019 if (num_of_supplies > ARRAY_SIZE(pdata->regulator)) {
1020 dev_err(dev, "%s: Num of supplies %u > max supported %u\n",
1021 __func__, num_of_supplies, ARRAY_SIZE(pdata->regulator));
1022
1023 goto err;
1024 }
1025
1026 for (i = 0; i < num_of_supplies; i++) {
1027 ret = wcd9xxx_dt_parse_vreg_info(dev, &pdata->regulator[i],
1028 codec_supplies[i]);
1029 if (ret)
1030 goto err;
1031 }
1032
1033 ret = wcd9xxx_dt_parse_micbias_info(dev, &pdata->micbias);
1034 if (ret)
1035 goto err;
1036
1037 pdata->reset_gpio = of_get_named_gpio(dev->of_node,
1038 "qcom,cdc-reset-gpio", 0);
1039 if (pdata->reset_gpio < 0) {
1040 dev_err(dev, "Looking up %s property in node %s failed %d\n",
1041 "qcom, cdc-reset-gpio", dev->of_node->full_name,
1042 pdata->reset_gpio);
1043 goto err;
1044 }
1045 pdata->irq = -1;
1046
1047 ret = wcd9xxx_dt_parse_slim_interface_dev_info(dev,
1048 &pdata->slimbus_slave_device);
1049 if (ret)
1050 goto err;
1051 return pdata;
1052err:
1053 devm_kfree(dev, pdata);
1054 return NULL;
1055}
1056
Joonwoo Park3c5b2df2012-08-28 15:36:55 -07001057static int wcd9xxx_slim_get_laddr(struct slim_device *sb,
1058 const u8 *e_addr, u8 e_len, u8 *laddr)
1059{
1060 int ret;
1061 const unsigned long timeout = jiffies +
1062 msecs_to_jiffies(SLIMBUS_PRESENT_TIMEOUT);
1063
1064 do {
1065 ret = slim_get_logical_addr(sb, e_addr, e_len, laddr);
1066 if (!ret)
1067 break;
1068 /* Give SLIMBUS time to report present and be ready. */
1069 usleep_range(1000, 1000);
1070 pr_debug_ratelimited("%s: retyring get logical addr\n",
1071 __func__);
1072 } while time_before(jiffies, timeout);
1073
1074 return ret;
1075}
1076
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +05301077static int wcd9xxx_slim_probe(struct slim_device *slim)
1078{
1079 struct wcd9xxx *wcd9xxx;
1080 struct wcd9xxx_pdata *pdata;
1081 int ret = 0;
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +05301082
Kiran Kandi725f8492012-08-06 13:45:16 -07001083 if (slim->dev.of_node) {
1084 dev_info(&slim->dev, "Platform data from device tree\n");
1085 pdata = wcd9xxx_populate_dt_pdata(&slim->dev);
1086 slim->dev.platform_data = pdata;
1087
1088 } else {
1089 dev_info(&slim->dev, "Platform data from board file\n");
1090 pdata = slim->dev.platform_data;
1091 }
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +05301092
1093 if (!pdata) {
1094 dev_err(&slim->dev, "Error, no platform data\n");
1095 ret = -EINVAL;
1096 goto err;
1097 }
1098
1099 wcd9xxx = kzalloc(sizeof(struct wcd9xxx), GFP_KERNEL);
1100 if (wcd9xxx == NULL) {
1101 pr_err("%s: error, allocation failed\n", __func__);
1102 ret = -ENOMEM;
1103 goto err;
1104 }
1105 if (!slim->ctrl) {
1106 pr_err("Error, no SLIMBUS control data\n");
1107 ret = -EINVAL;
1108 goto err_codec;
1109 }
1110 wcd9xxx->slim = slim;
1111 slim_set_clientdata(slim, wcd9xxx);
1112 wcd9xxx->reset_gpio = pdata->reset_gpio;
1113 wcd9xxx->dev = &slim->dev;
1114
Venkat Sudhirdb7aa2b2012-05-15 15:06:14 -07001115 ret = wcd9xxx_enable_supplies(wcd9xxx, pdata);
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +05301116 if (ret)
1117 goto err_codec;
1118 usleep_range(5, 5);
1119
1120 ret = wcd9xxx_reset(wcd9xxx);
1121 if (ret) {
1122 pr_err("%s: Resetting Codec failed\n", __func__);
1123 goto err_supplies;
1124 }
1125
Joonwoo Park3c5b2df2012-08-28 15:36:55 -07001126 ret = wcd9xxx_slim_get_laddr(wcd9xxx->slim, wcd9xxx->slim->e_addr,
1127 ARRAY_SIZE(wcd9xxx->slim->e_addr),
1128 &wcd9xxx->slim->laddr);
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +05301129 if (ret) {
Joonwoo Park3c5b2df2012-08-28 15:36:55 -07001130 pr_err("%s: failed to get slimbus %s logical address: %d\n",
1131 __func__, wcd9xxx->slim->name, ret);
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +05301132 goto err_reset;
1133 }
1134 wcd9xxx->read_dev = wcd9xxx_slim_read_device;
1135 wcd9xxx->write_dev = wcd9xxx_slim_write_device;
1136 wcd9xxx->irq = pdata->irq;
1137 wcd9xxx->irq_base = pdata->irq_base;
1138 wcd9xxx_pgd_la = wcd9xxx->slim->laddr;
1139
1140 if (pdata->num_irqs < TABLA_NUM_IRQS) {
1141 pr_err("%s: Error, not enough interrupt lines allocated\n",
1142 __func__);
1143 goto err_reset;
1144 }
1145
1146 wcd9xxx->slim_slave = &pdata->slimbus_slave_device;
1147
1148 ret = slim_add_device(slim->ctrl, wcd9xxx->slim_slave);
1149 if (ret) {
1150 pr_err("%s: error, adding SLIMBUS device failed\n", __func__);
1151 goto err_reset;
1152 }
1153
Joonwoo Park3c5b2df2012-08-28 15:36:55 -07001154 ret = wcd9xxx_slim_get_laddr(wcd9xxx->slim_slave,
1155 wcd9xxx->slim_slave->e_addr,
1156 ARRAY_SIZE(wcd9xxx->slim_slave->e_addr),
1157 &wcd9xxx->slim_slave->laddr);
1158 if (ret) {
1159 pr_err("%s: failed to get slimbus %s logical address: %d\n",
1160 __func__, wcd9xxx->slim->name, ret);
1161 goto err_slim_add;
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +05301162 }
1163 wcd9xxx_inf_la = wcd9xxx->slim_slave->laddr;
1164 wcd9xxx_intf = WCD9XXX_INTERFACE_TYPE_SLIMBUS;
1165
1166 ret = wcd9xxx_device_init(wcd9xxx, wcd9xxx->irq);
1167 if (ret) {
1168 pr_err("%s: error, initializing device failed\n", __func__);
1169 goto err_slim_add;
1170 }
Joonwoo Parka7172112012-07-23 16:03:49 -07001171
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +05301172 wcd9xxx_init_slimslave(wcd9xxx, wcd9xxx_pgd_la);
Joonwoo Parka7172112012-07-23 16:03:49 -07001173
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +05301174#ifdef CONFIG_DEBUG_FS
1175 debugCodec = wcd9xxx;
1176
1177 debugfs_wcd9xxx_dent = debugfs_create_dir
1178 ("wcd9310_slimbus_interface_device", 0);
1179 if (!IS_ERR(debugfs_wcd9xxx_dent)) {
1180 debugfs_peek = debugfs_create_file("peek",
1181 S_IFREG | S_IRUGO, debugfs_wcd9xxx_dent,
1182 (void *) "peek", &codec_debug_ops);
1183
1184 debugfs_poke = debugfs_create_file("poke",
1185 S_IFREG | S_IRUGO, debugfs_wcd9xxx_dent,
1186 (void *) "poke", &codec_debug_ops);
1187 }
1188#endif
1189
1190 return ret;
1191
1192err_slim_add:
1193 slim_remove_device(wcd9xxx->slim_slave);
1194err_reset:
1195 wcd9xxx_free_reset(wcd9xxx);
1196err_supplies:
Venkat Sudhir49203862012-05-21 14:29:13 -07001197 wcd9xxx_disable_supplies(wcd9xxx, pdata);
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +05301198err_codec:
1199 kfree(wcd9xxx);
1200err:
1201 return ret;
1202}
1203static int wcd9xxx_slim_remove(struct slim_device *pdev)
1204{
1205 struct wcd9xxx *wcd9xxx;
Venkat Sudhir49203862012-05-21 14:29:13 -07001206 struct wcd9xxx_pdata *pdata = pdev->dev.platform_data;
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +05301207
1208#ifdef CONFIG_DEBUG_FS
1209 debugfs_remove(debugfs_peek);
1210 debugfs_remove(debugfs_poke);
1211 debugfs_remove(debugfs_wcd9xxx_dent);
1212#endif
1213 wcd9xxx = slim_get_devicedata(pdev);
1214 wcd9xxx_deinit_slimslave(wcd9xxx);
1215 slim_remove_device(wcd9xxx->slim_slave);
Venkat Sudhir49203862012-05-21 14:29:13 -07001216 wcd9xxx_disable_supplies(wcd9xxx, pdata);
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +05301217 wcd9xxx_device_exit(wcd9xxx);
1218 return 0;
1219}
1220
1221static int wcd9xxx_resume(struct wcd9xxx *wcd9xxx)
1222{
1223 int ret = 0;
1224
1225 pr_debug("%s: enter\n", __func__);
1226 mutex_lock(&wcd9xxx->pm_lock);
1227 if (wcd9xxx->pm_state == WCD9XXX_PM_ASLEEP) {
1228 pr_debug("%s: resuming system, state %d, wlock %d\n", __func__,
1229 wcd9xxx->pm_state, wcd9xxx->wlock_holders);
1230 wcd9xxx->pm_state = WCD9XXX_PM_SLEEPABLE;
1231 } else {
1232 pr_warn("%s: system is already awake, state %d wlock %d\n",
1233 __func__, wcd9xxx->pm_state, wcd9xxx->wlock_holders);
1234 }
1235 mutex_unlock(&wcd9xxx->pm_lock);
1236 wake_up_all(&wcd9xxx->pm_wq);
1237
1238 return ret;
1239}
1240
1241static int wcd9xxx_slim_resume(struct slim_device *sldev)
1242{
1243 struct wcd9xxx *wcd9xxx = slim_get_devicedata(sldev);
1244 return wcd9xxx_resume(wcd9xxx);
1245}
1246
1247static int wcd9xxx_i2c_resume(struct i2c_client *i2cdev)
1248{
1249 struct wcd9xxx *wcd9xxx = dev_get_drvdata(&i2cdev->dev);
Asish Bhattacharyab86c3472012-02-15 08:31:52 +05301250 if (wcd9xxx)
1251 return wcd9xxx_resume(wcd9xxx);
1252 else
1253 return 0;
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +05301254}
1255
1256static int wcd9xxx_suspend(struct wcd9xxx *wcd9xxx, pm_message_t pmesg)
1257{
1258 int ret = 0;
1259
1260 pr_debug("%s: enter\n", __func__);
Stephen Boyd2fcabf92012-05-30 10:41:11 -07001261 /*
1262 * pm_qos_update_request() can be called after this suspend chain call
1263 * started. thus suspend can be called while lock is being held
1264 */
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +05301265 mutex_lock(&wcd9xxx->pm_lock);
1266 if (wcd9xxx->pm_state == WCD9XXX_PM_SLEEPABLE) {
1267 pr_debug("%s: suspending system, state %d, wlock %d\n",
1268 __func__, wcd9xxx->pm_state, wcd9xxx->wlock_holders);
1269 wcd9xxx->pm_state = WCD9XXX_PM_ASLEEP;
1270 } else if (wcd9xxx->pm_state == WCD9XXX_PM_AWAKE) {
1271 /* unlock to wait for pm_state == WCD9XXX_PM_SLEEPABLE
1272 * then set to WCD9XXX_PM_ASLEEP */
1273 pr_debug("%s: waiting to suspend system, state %d, wlock %d\n",
1274 __func__, wcd9xxx->pm_state, wcd9xxx->wlock_holders);
1275 mutex_unlock(&wcd9xxx->pm_lock);
1276 if (!(wait_event_timeout(wcd9xxx->pm_wq,
1277 wcd9xxx_pm_cmpxchg(wcd9xxx,
1278 WCD9XXX_PM_SLEEPABLE,
1279 WCD9XXX_PM_ASLEEP) ==
1280 WCD9XXX_PM_SLEEPABLE,
1281 HZ))) {
1282 pr_debug("%s: suspend failed state %d, wlock %d\n",
1283 __func__, wcd9xxx->pm_state,
1284 wcd9xxx->wlock_holders);
1285 ret = -EBUSY;
1286 } else {
1287 pr_debug("%s: done, state %d, wlock %d\n", __func__,
1288 wcd9xxx->pm_state, wcd9xxx->wlock_holders);
1289 }
1290 mutex_lock(&wcd9xxx->pm_lock);
1291 } else if (wcd9xxx->pm_state == WCD9XXX_PM_ASLEEP) {
1292 pr_warn("%s: system is already suspended, state %d, wlock %dn",
1293 __func__, wcd9xxx->pm_state, wcd9xxx->wlock_holders);
1294 }
1295 mutex_unlock(&wcd9xxx->pm_lock);
1296
1297 return ret;
1298}
1299
1300static int wcd9xxx_slim_suspend(struct slim_device *sldev, pm_message_t pmesg)
1301{
1302 struct wcd9xxx *wcd9xxx = slim_get_devicedata(sldev);
1303 return wcd9xxx_suspend(wcd9xxx, pmesg);
1304}
1305
1306static int wcd9xxx_i2c_suspend(struct i2c_client *i2cdev, pm_message_t pmesg)
1307{
1308 struct wcd9xxx *wcd9xxx = dev_get_drvdata(&i2cdev->dev);
Asish Bhattacharyab86c3472012-02-15 08:31:52 +05301309 if (wcd9xxx)
1310 return wcd9xxx_suspend(wcd9xxx, pmesg);
1311 else
1312 return 0;
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +05301313}
1314
Asish Bhattacharyab86c3472012-02-15 08:31:52 +05301315static const struct slim_device_id sitar_slimtest_id[] = {
1316 {"sitar-slim", 0},
1317 {}
1318};
1319static struct slim_driver sitar_slim_driver = {
1320 .driver = {
1321 .name = "sitar-slim",
1322 .owner = THIS_MODULE,
1323 },
1324 .probe = wcd9xxx_slim_probe,
1325 .remove = wcd9xxx_slim_remove,
1326 .id_table = sitar_slimtest_id,
1327 .resume = wcd9xxx_slim_resume,
1328 .suspend = wcd9xxx_slim_suspend,
1329};
1330
Bhalchandra Gajare83c81f62012-05-18 16:09:05 -07001331static const struct slim_device_id sitar1p1_slimtest_id[] = {
1332 {"sitar1p1-slim", 0},
1333 {}
1334};
1335static struct slim_driver sitar1p1_slim_driver = {
1336 .driver = {
1337 .name = "sitar1p1-slim",
1338 .owner = THIS_MODULE,
1339 },
1340 .probe = wcd9xxx_slim_probe,
1341 .remove = wcd9xxx_slim_remove,
1342 .id_table = sitar1p1_slimtest_id,
1343 .resume = wcd9xxx_slim_resume,
1344 .suspend = wcd9xxx_slim_suspend,
1345};
1346
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +05301347static const struct slim_device_id slimtest_id[] = {
1348 {"tabla-slim", 0},
1349 {}
1350};
1351
1352static struct slim_driver tabla_slim_driver = {
1353 .driver = {
1354 .name = "tabla-slim",
1355 .owner = THIS_MODULE,
1356 },
1357 .probe = wcd9xxx_slim_probe,
1358 .remove = wcd9xxx_slim_remove,
1359 .id_table = slimtest_id,
1360 .resume = wcd9xxx_slim_resume,
1361 .suspend = wcd9xxx_slim_suspend,
1362};
1363
1364static const struct slim_device_id slimtest2x_id[] = {
1365 {"tabla2x-slim", 0},
1366 {}
1367};
1368
1369static struct slim_driver tabla2x_slim_driver = {
1370 .driver = {
1371 .name = "tabla2x-slim",
1372 .owner = THIS_MODULE,
1373 },
1374 .probe = wcd9xxx_slim_probe,
1375 .remove = wcd9xxx_slim_remove,
1376 .id_table = slimtest2x_id,
1377 .resume = wcd9xxx_slim_resume,
1378 .suspend = wcd9xxx_slim_suspend,
1379};
1380
Joonwoo Parka7172112012-07-23 16:03:49 -07001381static const struct slim_device_id taiko_slimtest_id[] = {
Kiran Kandi725f8492012-08-06 13:45:16 -07001382 {"taiko-slim-pgd", 0},
Joonwoo Parka7172112012-07-23 16:03:49 -07001383 {}
1384};
1385
1386static struct slim_driver taiko_slim_driver = {
1387 .driver = {
1388 .name = "taiko-slim",
1389 .owner = THIS_MODULE,
1390 },
1391 .probe = wcd9xxx_slim_probe,
1392 .remove = wcd9xxx_slim_remove,
1393 .id_table = taiko_slimtest_id,
1394 .resume = wcd9xxx_slim_resume,
1395 .suspend = wcd9xxx_slim_suspend,
1396};
1397
Asish Bhattacharya2b709d42011-11-15 10:39:23 +05301398#define WCD9XXX_I2C_TOP_LEVEL 0
1399#define WCD9XXX_I2C_ANALOG 1
1400#define WCD9XXX_I2C_DIGITAL_1 2
1401#define WCD9XXX_I2C_DIGITAL_2 3
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +05301402
1403static struct i2c_device_id tabla_id_table[] = {
Asish Bhattacharya2b709d42011-11-15 10:39:23 +05301404 {"tabla top level", WCD9XXX_I2C_TOP_LEVEL},
1405 {"tabla analog", WCD9XXX_I2C_ANALOG},
1406 {"tabla digital1", WCD9XXX_I2C_DIGITAL_1},
1407 {"tabla digital2", WCD9XXX_I2C_DIGITAL_2},
1408 {}
1409};
1410MODULE_DEVICE_TABLE(i2c, tabla_id_table);
1411
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +05301412static struct i2c_driver tabla_i2c_driver = {
1413 .driver = {
1414 .owner = THIS_MODULE,
1415 .name = "tabla-i2c-core",
1416 },
1417 .id_table = tabla_id_table,
1418 .probe = wcd9xxx_i2c_probe,
1419 .remove = __devexit_p(wcd9xxx_i2c_remove),
1420 .resume = wcd9xxx_i2c_resume,
1421 .suspend = wcd9xxx_i2c_suspend,
1422};
1423
1424static int __init wcd9xxx_init(void)
1425{
Joonwoo Parka7172112012-07-23 16:03:49 -07001426 int ret1, ret2, ret3, ret4, ret5, ret6;
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +05301427
1428 ret1 = slim_driver_register(&tabla_slim_driver);
1429 if (ret1 != 0)
1430 pr_err("Failed to register tabla SB driver: %d\n", ret1);
1431
1432 ret2 = slim_driver_register(&tabla2x_slim_driver);
1433 if (ret2 != 0)
1434 pr_err("Failed to register tabla2x SB driver: %d\n", ret2);
1435
1436 ret3 = i2c_add_driver(&tabla_i2c_driver);
1437 if (ret3 != 0)
1438 pr_err("failed to add the I2C driver\n");
1439
Asish Bhattacharyab86c3472012-02-15 08:31:52 +05301440 ret4 = slim_driver_register(&sitar_slim_driver);
Bhalchandra Gajare83c81f62012-05-18 16:09:05 -07001441 if (ret4 != 0)
Asish Bhattacharyab86c3472012-02-15 08:31:52 +05301442 pr_err("Failed to register sitar SB driver: %d\n", ret4);
1443
Bhalchandra Gajare83c81f62012-05-18 16:09:05 -07001444 ret5 = slim_driver_register(&sitar1p1_slim_driver);
1445 if (ret5 != 0)
1446 pr_err("Failed to register sitar SB driver: %d\n", ret5);
1447
Joonwoo Parka7172112012-07-23 16:03:49 -07001448 ret6 = slim_driver_register(&taiko_slim_driver);
1449 if (ret6 != 0)
1450 pr_err("Failed to register taiko SB driver: %d\n", ret6);
1451
1452 return (ret1 && ret2 && ret3 && ret4 && ret5 && ret6) ? -1 : 0;
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +05301453}
1454module_init(wcd9xxx_init);
1455
1456static void __exit wcd9xxx_exit(void)
1457{
1458}
1459module_exit(wcd9xxx_exit);
1460
1461MODULE_DESCRIPTION("Codec core driver");
1462MODULE_VERSION("1.0");
1463MODULE_LICENSE("GPL v2");