Revert "media: camera config changes"
[linux-2.6.git] / drivers / media / video / tegra / tps61050.c
1 /*
2  * tps61050.c - tps61050 flash/torch kernel driver
3  *
4  * Copyright (C) 2011 NVIDIA Corporation.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
18  * 02111-1307, USA
19  */
20
21 /* Implementation
22  * --------------
23  * The board level details about the device need to be provided in the board
24  * file with the tps61050_platform_data structure.
25  * Standard among NVC kernel drivers in this structure is:
26  * .cfg = Use the NVC_CFG_ defines that are in nvc_torch.h.
27  *        Descriptions of the configuration options are with the defines.
28  *        This value is typically 0.
29  * .num = The number of the instance of the device.  This should start at 1 and
30  *        and increment for each device on the board.  This number will be
31  *        appended to the MISC driver name, Example: /dev/tps61050.1
32  * .sync = If there is a need to synchronize two devices, then this value is
33  *         the number of the device instance this device is allowed to sync to.
34  *         This is typically used for stereo applications.
35  * .dev_name = The MISC driver name the device registers as.  If not used,
36  *             then the part number of the device is used for the driver name.
37  *             If using the NVC user driver then use the name found in this
38  *             driver under _default_pdata.
39  *
40  * The following is specific to NVC kernel flash/torch drivers:
41  * .pinstate = a pointer to the nvc_torch_pin_state structure.  This
42  *             structure gives the details of which VI GPIO to use to trigger
43  *             the flash.  The mask tells which pin and the values is the
44  *             level.  For example, if VI GPIO pin 6 is used, then
45  *             .mask = 0x0040
46  *             .values = 0x0040
47  *             If VI GPIO pin 0 is used, then
48  *             .mask = 0x0001
49  *             .values = 0x0001
50  *             This is typically just one pin but there is some legacy
51  *             here that insinuates more than one pin can be used.
52  *             When the flash level is set, then the driver will return the
53  *             value in values.  When the flash level is off, the driver will
54  *             return 0 for the values to deassert the signal.
55  *             If a VI GPIO is not used, then the mask and values must be set
56  *             to 0.  The flash may then be triggered via I2C instead.
57  *             However, a VI GPIO is strongly encouraged since it allows
58  *             tighter timing with the picture taken as well as reduced power
59  *             by asserting the trigger signal for only when needed.
60  * .max_amp_torch = Is the maximum torch value allowed.  The value is 0 to
61  *                  _MAX_TORCH_LEVEL.  This is to allow a limit to the amount
62  *                  of amps used.  If left blank then _MAX_TORCH_LEVEL will be
63  *                  used.
64  * .max_amp_flash = Is the maximum flash value allowed.  The value is 0 to
65  *                  _MAX_FLASH_LEVEL.  This is to allow a limit to the amount
66  *                  of amps used.  If left blank then _MAX_FLASH_LEVEL will be
67  *                  used.
68  *
69  * The following is specific to only this NVC kernel flash/torch driver:
70  * N/A
71  *
72  * Power Requirements
73  * The board power file must contain the following labels for the power
74  * regulator(s) of this device:
75  * "vdd_i2c" = the power regulator for the I2C power.
76  * Note that this device is typically connected directly to the battery rail
77  * and does not need a source power regulator (vdd).
78  *
79  * The above values should be all that is needed to use the device with this
80  * driver.  Modifications of this driver should not be needed.
81  */
82
83
84 #include <linux/fs.h>
85 #include <linux/i2c.h>
86 #include <linux/miscdevice.h>
87 #include <linux/slab.h>
88 #include <linux/delay.h>
89 #include <linux/uaccess.h>
90 #include <linux/list.h>
91 #include <linux/regulator/consumer.h>
92 #include <media/nvc.h>
93 #include <media/tps61050.h>
94
95 #define TPS61050_REG0           0x00
96 #define TPS61050_REG1           0x01
97 #define TPS61050_REG2           0x02
98 #define TPS61050_REG3           0x03
99 #define tps61050_flash_cap_size (sizeof(tps61050_flash_cap.numberoflevels) \
100                                 + (sizeof(tps61050_flash_cap.levels[0]) \
101                                 * (TPS61050_MAX_FLASH_LEVEL + 1)))
102 #define tps61050_torch_cap_size (sizeof(tps61050_torch_cap.numberoflevels) \
103                                 + (sizeof(tps61050_torch_cap.guidenum[0]) \
104                                 * (TPS61050_MAX_TORCH_LEVEL + 1)))
105
106
107 static struct nvc_torch_flash_capabilities tps61050_flash_cap = {
108         TPS61050_MAX_FLASH_LEVEL + 1,
109         {
110                 { 0,   0xFFFFFFFF, 0 },
111                 { 150, 558,        2 },
112                 { 200, 558,        2 },
113                 { 300, 558,        2 },
114                 { 400, 558,        2 },
115                 { 500, 558,        2 },
116                 { 700, 558,        2 },
117                 { 900, 558,        2 },
118                 { 900, 558,        2 }
119         }
120 };
121
122 static struct nvc_torch_torch_capabilities tps61050_torch_cap = {
123         TPS61050_MAX_TORCH_LEVEL + 1,
124         {
125                 0,
126                 50,
127                 75,
128                 100,
129                 150,
130                 200,
131                 491,
132                 491
133         }
134 };
135
136 struct tps61050_info {
137         atomic_t in_use;
138         struct i2c_client *i2c_client;
139         struct tps61050_platform_data *pdata;
140         struct miscdevice miscdev;
141         struct list_head list;
142         int pwr_api;
143         int pwr_dev;
144         struct nvc_regulator vreg_i2c;
145         u8 s_mode;
146         struct tps61050_info *s_info;
147 };
148
149 static struct nvc_torch_pin_state tps61050_default_pinstate = {
150         .mask           = 0x0000,
151         .values         = 0x0000,
152 };
153
154 static struct tps61050_platform_data tps61050_default_pdata = {
155         .cfg            = 0,
156         .num            = 0,
157         .sync           = 0,
158         .dev_name       = "torch",
159         .pinstate       = &tps61050_default_pinstate,
160         .max_amp_torch  = TPS61050_MAX_TORCH_LEVEL,
161         .max_amp_flash  = TPS61050_MAX_FLASH_LEVEL,
162 };
163
164 static LIST_HEAD(tps61050_info_list);
165 static DEFINE_SPINLOCK(tps61050_spinlock);
166
167
168 static int tps61050_i2c_rd(struct tps61050_info *info, u8 reg, u8 *val)
169 {
170         struct i2c_msg msg[2];
171         u8 buf[2];
172
173         buf[0] = reg;
174         msg[0].addr = info->i2c_client->addr;
175         msg[0].flags = 0;
176         msg[0].len = 1;
177         msg[0].buf = &buf[0];
178         msg[1].addr = info->i2c_client->addr;
179         msg[1].flags = I2C_M_RD;
180         msg[1].len = 1;
181         msg[1].buf = &buf[1];
182         *val = 0;
183         if (i2c_transfer(info->i2c_client->adapter, msg, 2) != 2)
184                 return -EIO;
185
186         *val = buf[1];
187         return 0;
188 }
189
190 static int tps61050_i2c_wr(struct tps61050_info *info, u8 reg, u8 val)
191 {
192         struct i2c_msg msg;
193         u8 buf[2];
194
195         buf[0] = reg;
196         buf[1] = val;
197         msg.addr = info->i2c_client->addr;
198         msg.flags = 0;
199         msg.len = 2;
200         msg.buf = &buf[0];
201         if (i2c_transfer(info->i2c_client->adapter, &msg, 1) != 1)
202                 return -EIO;
203
204         return 0;
205 }
206
207 static void tps61050_pm_regulator_put(struct nvc_regulator *sreg)
208 {
209         regulator_put(sreg->vreg);
210         sreg->vreg = NULL;
211 }
212
213 static int tps61050_pm_regulator_get(struct tps61050_info *info,
214                                      struct nvc_regulator *sreg,
215                                      char vreg_name[])
216 {
217         int err = 0;
218
219         sreg->vreg_flag = 0;
220         sreg->vreg = regulator_get(&info->i2c_client->dev, vreg_name);
221         if (IS_ERR_OR_NULL(sreg->vreg)) {
222                 dev_err(&info->i2c_client->dev,
223                                 "%s err for regulator: %s err: %d\n",
224                                 __func__, vreg_name, (int)sreg->vreg);
225                 err = PTR_ERR(sreg->vreg);
226                 sreg->vreg = NULL;
227         } else {
228                 sreg->vreg_name = vreg_name;
229                 dev_dbg(&info->i2c_client->dev,
230                                 "%s vreg_name: %s\n",
231                                 __func__, sreg->vreg_name);
232         }
233         return err;
234 }
235
236 static int tps61050_pm_regulator_en(struct tps61050_info *info,
237                                     struct nvc_regulator *sreg)
238 {
239         int err = 0;
240
241         if (!sreg->vreg_flag && (sreg->vreg != NULL)) {
242                 err = regulator_enable(sreg->vreg);
243                 if (!err) {
244                         dev_dbg(&info->i2c_client->dev,
245                                         "%s vreg_name: %s\n",
246                                         __func__, sreg->vreg_name);
247                         sreg->vreg_flag = 1;
248                         err = 1; /* flag regulator state change */
249                         mdelay(5); /* device powerup delay */
250                 } else {
251                         dev_err(&info->i2c_client->dev,
252                                         "%s err, regulator: %s\n",
253                                         __func__, sreg->vreg_name);
254                 }
255         }
256         return err;
257 }
258
259 static int tps61050_pm_regulator_dis(struct tps61050_info *info,
260                                      struct nvc_regulator *sreg)
261 {
262         int err = 0;
263
264         if (sreg->vreg_flag && (sreg->vreg != NULL)) {
265                 err = regulator_disable(sreg->vreg);
266                 if (!err)
267                         dev_dbg(&info->i2c_client->dev,
268                                         "%s vreg_name: %s\n",
269                                         __func__, sreg->vreg_name);
270                 else
271                         dev_err(&info->i2c_client->dev,
272                                         "%s err, regulator: %s\n",
273                                         __func__, sreg->vreg_name);
274         }
275         sreg->vreg_flag = 0;
276         return err;
277 }
278
279 static int tps61050_pm_wr(struct tps61050_info *info, int pwr)
280 {
281         int err = 0;
282         u8 reg;
283
284         if (pwr == info->pwr_dev)
285                 return 0;
286
287         switch (pwr) {
288         case NVC_PWR_OFF:
289                 if ((info->pdata->cfg & NVC_CFG_OFF2STDBY) ||
290                              (info->pdata->cfg & NVC_CFG_BOOT_INIT)) {
291                         pwr = NVC_PWR_STDBY;
292                 } else {
293                         err = tps61050_pm_regulator_en(info, &info->vreg_i2c);
294                         err |= tps61050_i2c_wr(info, TPS61050_REG0, 0x00);
295                         err |= tps61050_i2c_wr(info, TPS61050_REG1, 0x00);
296                         err |= tps61050_pm_regulator_dis(info, &info->vreg_i2c);
297                         break;
298                 }
299         case NVC_PWR_STDBY_OFF:
300                 if ((info->pdata->cfg & NVC_CFG_OFF2STDBY) ||
301                              (info->pdata->cfg & NVC_CFG_BOOT_INIT)) {
302                         pwr = NVC_PWR_STDBY;
303                 } else {
304                         err = tps61050_pm_regulator_en(info, &info->vreg_i2c);
305                         err |= tps61050_i2c_wr(info, TPS61050_REG0, 0x00);
306                         err |= tps61050_i2c_wr(info, TPS61050_REG1, 0x00);
307                         break;
308                 }
309         case NVC_PWR_STDBY:
310                 err = tps61050_pm_regulator_en(info, &info->vreg_i2c);
311                 err |= tps61050_i2c_rd(info, TPS61050_REG0, &reg);
312                 reg &= 0x3F; /* 7:6 = mode */
313                 err |= tps61050_i2c_wr(info, TPS61050_REG0, reg);
314                 break;
315
316         case NVC_PWR_COMM:
317         case NVC_PWR_ON:
318                 err = tps61050_pm_regulator_en(info, &info->vreg_i2c);
319                 break;
320
321         default:
322                 err = -EINVAL;
323                 break;
324         }
325
326         if (err < 0) {
327                 dev_err(&info->i2c_client->dev, "%s error\n", __func__);
328                 pwr = NVC_PWR_ERR;
329         }
330         info->pwr_dev = pwr;
331         if (err > 0)
332                 return 0;
333
334         return err;
335 }
336
337 static int tps61050_pm_wr_s(struct tps61050_info *info, int pwr)
338 {
339         int err1 = 0;
340         int err2 = 0;
341
342         if ((info->s_mode == NVC_SYNC_OFF) ||
343                         (info->s_mode == NVC_SYNC_MASTER) ||
344                         (info->s_mode == NVC_SYNC_STEREO))
345                 err1 = tps61050_pm_wr(info, pwr);
346         if ((info->s_mode == NVC_SYNC_SLAVE) ||
347                         (info->s_mode == NVC_SYNC_STEREO))
348                 err2 = tps61050_pm_wr(info->s_info, pwr);
349         return err1 | err2;
350 }
351
352 static int tps61050_pm_api_wr(struct tps61050_info *info, int pwr)
353 {
354         int err = 0;
355
356         if (!pwr || (pwr > NVC_PWR_ON))
357                 return 0;
358
359         if (pwr > info->pwr_dev)
360                 err = tps61050_pm_wr_s(info, pwr);
361         if (!err)
362                 info->pwr_api = pwr;
363         else
364                 info->pwr_api = NVC_PWR_ERR;
365         if (info->pdata->cfg & NVC_CFG_NOERR)
366                 return 0;
367
368         return err;
369 }
370
371 static int tps61050_pm_dev_wr(struct tps61050_info *info, int pwr)
372 {
373         if (pwr < info->pwr_api)
374                 pwr = info->pwr_api;
375         return tps61050_pm_wr(info, pwr);
376 }
377
378 static void tps61050_pm_exit(struct tps61050_info *info)
379 {
380         tps61050_pm_wr_s(info, NVC_PWR_OFF);
381         tps61050_pm_regulator_put(&info->vreg_i2c);
382 }
383
384 static void tps61050_pm_init(struct tps61050_info *info)
385 {
386         tps61050_pm_regulator_get(info, &info->vreg_i2c, "vdd_i2c");
387 }
388
389 struct tps61050_reg_init {
390         u8 mask;
391         u8 val;
392 };
393
394 static struct tps61050_reg_init tps61050_reg_init_id[] = {
395         {0xC0, 0x00},
396         {0xC0, 0x00},
397         {0x87, 0x00},
398         {0xFF, 0xD1},
399 };
400
401 static int tps61050_dev_id(struct tps61050_info *info)
402 {
403         u8 reg;
404         u8 i;
405         int err;
406
407         tps61050_pm_dev_wr(info, NVC_PWR_COMM);
408         /* There isn't a device ID so we just check that all the registers
409          * equal their startup defaults.
410          */
411         for (i = TPS61050_REG0; i <= TPS61050_REG3; i++) {
412                 err = tps61050_i2c_rd(info, i, &reg);
413                 if (err) {
414                         break;
415                 } else {
416                         reg &= tps61050_reg_init_id[i].mask;
417                         if (reg != tps61050_reg_init_id[i].val) {
418                                 err = -ENODEV;
419                                 break;
420                         }
421                 }
422         }
423         tps61050_pm_dev_wr(info, NVC_PWR_OFF);
424         return err;
425 }
426
427 static int tps61050_param_rd(struct tps61050_info *info, long arg)
428 {
429         struct nvc_param params;
430         struct nvc_torch_pin_state pinstate;
431         const void *data_ptr;
432         u8 reg;
433         u32 data_size = 0;
434         int err;
435
436         if (copy_from_user(&params,
437                         (const void __user *)arg,
438                         sizeof(struct nvc_param))) {
439                 dev_err(&info->i2c_client->dev, "%s %d copy_from_user err\n",
440                                 __func__, __LINE__);
441                 return -EINVAL;
442         }
443
444         if (info->s_mode == NVC_SYNC_SLAVE)
445                 info = info->s_info;
446         switch (params.param) {
447         case NVC_PARAM_FLASH_CAPS:
448                 dev_dbg(&info->i2c_client->dev, "%s FLASH_CAPS\n", __func__);
449                 data_ptr = &tps61050_flash_cap;
450                 data_size = tps61050_flash_cap_size;
451                 break;
452
453         case NVC_PARAM_FLASH_LEVEL:
454                 tps61050_pm_dev_wr(info, NVC_PWR_COMM);
455                 err = tps61050_i2c_rd(info, TPS61050_REG1, &reg);
456                 tps61050_pm_dev_wr(info, NVC_PWR_OFF);
457                 if (err < 0)
458                         return err;
459
460                 if (reg & 0x80) { /* 7:7 flash on/off */
461                         reg &= 0x07; /* 2:0 flash setting */
462                         reg++; /* flash setting +1 if flash on */
463                 } else {
464                         reg = 0; /* flash is off */
465                 }
466                 dev_dbg(&info->i2c_client->dev, "%s FLASH_LEVEL: %u\n",
467                             __func__,
468                             (unsigned)tps61050_flash_cap.levels[reg].guidenum);
469                 data_ptr = &tps61050_flash_cap.levels[reg].guidenum;
470                 data_size = sizeof(tps61050_flash_cap.levels[reg].guidenum);
471                 break;
472
473         case NVC_PARAM_TORCH_CAPS:
474                 dev_dbg(&info->i2c_client->dev, "%s TORCH_CAPS\n", __func__);
475                 data_ptr = &tps61050_torch_cap;
476                 data_size = tps61050_torch_cap_size;
477                 break;
478
479         case NVC_PARAM_TORCH_LEVEL:
480                 tps61050_pm_dev_wr(info, NVC_PWR_COMM);
481                 err = tps61050_i2c_rd(info, TPS61050_REG0, &reg);
482                 tps61050_pm_dev_wr(info, NVC_PWR_OFF);
483                 if (err < 0)
484                         return err;
485
486                 reg &= 0x07;
487                 dev_dbg(&info->i2c_client->dev, "%s TORCH_LEVEL: %u\n",
488                                 __func__,
489                                 (unsigned)tps61050_torch_cap.guidenum[reg]);
490                 data_ptr = &tps61050_torch_cap.guidenum[reg];
491                 data_size = sizeof(tps61050_torch_cap.guidenum[reg]);
492                 break;
493
494         case NVC_PARAM_FLASH_PIN_STATE:
495                 pinstate.mask = info->pdata->pinstate->mask;
496                 tps61050_pm_dev_wr(info, NVC_PWR_COMM);
497                 err = tps61050_i2c_rd(info, TPS61050_REG1, &reg);
498                 tps61050_pm_dev_wr(info, NVC_PWR_OFF);
499                 if (err < 0)
500                         return err;
501
502                 reg &= 0x80; /* 7:7=flash enable */
503                 if (reg)
504                         /* assert strobe */
505                         pinstate.values = info->pdata->pinstate->values;
506                 else
507                         pinstate.values = 0; /* deassert strobe */
508                 dev_dbg(&info->i2c_client->dev, "%s FLASH_PIN_STATE: %x&%x\n",
509                                 __func__, pinstate.mask, pinstate.values);
510                 data_ptr = &pinstate;
511                 data_size = sizeof(struct nvc_torch_pin_state);
512                 break;
513
514         case NVC_PARAM_STEREO:
515                 dev_dbg(&info->i2c_client->dev, "%s STEREO: %d\n",
516                                 __func__, (int)info->s_mode);
517                 data_ptr = &info->s_mode;
518                 data_size = sizeof(info->s_mode);
519                 break;
520
521         default:
522                 dev_err(&info->i2c_client->dev,
523                                 "%s unsupported parameter: %d\n",
524                                 __func__, params.param);
525                 return -EINVAL;
526         }
527
528         if (params.sizeofvalue < data_size) {
529                 dev_err(&info->i2c_client->dev,
530                                 "%s data size mismatch %d != %d\n",
531                                 __func__, params.sizeofvalue, data_size);
532                 return -EINVAL;
533         }
534
535         if (copy_to_user((void __user *)params.p_value,
536                          data_ptr,
537                          data_size)) {
538                 dev_err(&info->i2c_client->dev,
539                                 "%s copy_to_user err line %d\n",
540                                 __func__, __LINE__);
541                 return -EFAULT;
542         }
543
544         return 0;
545 }
546
547 static int tps61050_param_wr_s(struct tps61050_info *info,
548                                struct nvc_param *params,
549                                u8 val)
550 {
551         u8 reg;
552         int err = 0;
553
554         /*
555          * 7:6 flash/torch mode
556          * 0 0 = off (power save)
557          * 0 1 = torch only (torch power is 2:0 REG0 where 0 = off)
558          * 1 0 = flash and torch (flash power is 2:0 REG1 (0 is a power level))
559          * 1 1 = N/A
560          * Note that 7:6 of REG0 and REG1 are shadowed with each other.
561          * In the code below we want to turn on/off one
562          * without affecting the other.
563          */
564         switch (params->param) {
565         case NVC_PARAM_FLASH_LEVEL:
566                 dev_dbg(&info->i2c_client->dev, "%s FLASH_LEVEL: %d\n",
567                                 __func__, val);
568                 tps61050_pm_dev_wr(info, NVC_PWR_ON);
569                 if (val) {
570                         val--;
571                         if (val > tps61050_default_pdata.max_amp_flash)
572                                 val = tps61050_default_pdata.max_amp_flash;
573                         /* Amp limit values are in the board-sensors file. */
574                         if (info->pdata->max_amp_flash &&
575                                         (val > info->pdata->max_amp_flash))
576                                 val = info->pdata->max_amp_flash;
577                         val |= 0x80; /* 7:7=flash mode */
578                 } else {
579                         err = tps61050_i2c_rd(info, TPS61050_REG0, &reg);
580                         if (reg & 0x07) /* 2:0=torch setting */
581                                 val = 0x40; /* 6:6 enable just torch */
582                 }
583                 err |= tps61050_i2c_wr(info, TPS61050_REG1, val);
584                 val &= 0xC0; /* 7:6=flash/torch mode */
585                 if (!val) /* turn pwr off if no flash && no pwr_api */
586                         tps61050_pm_dev_wr(info, NVC_PWR_OFF);
587                 return err;
588
589         case NVC_PARAM_TORCH_LEVEL:
590                 dev_dbg(&info->i2c_client->dev, "%s TORCH_LEVEL: %d\n",
591                                 __func__, val);
592                 tps61050_pm_dev_wr(info, NVC_PWR_ON);
593                 err = tps61050_i2c_rd(info, TPS61050_REG1, &reg);
594                 reg &= 0x80; /* 7:7=flash */
595                 if (val) {
596                         if (val > tps61050_default_pdata.max_amp_torch)
597                                 val = tps61050_default_pdata.max_amp_torch;
598                         /* Amp limit values are in the board-sensors file. */
599                         if (info->pdata->max_amp_torch &&
600                                         (val > info->pdata->max_amp_torch))
601                                 val = info->pdata->max_amp_torch;
602                         if (!reg) /* test if flash/torch off */
603                                 val |= (0x40); /* 6:6=torch only mode */
604                 } else {
605                         val |= reg;
606                 }
607                 err |= tps61050_i2c_wr(info, TPS61050_REG0, val);
608                 val &= 0xC0; /* 7:6=mode */
609                 if (!val) /* turn pwr off if no torch && no pwr_api */
610                         tps61050_pm_dev_wr(info, NVC_PWR_OFF);
611                 return err;
612
613         case NVC_PARAM_FLASH_PIN_STATE:
614                 dev_dbg(&info->i2c_client->dev, "%s FLASH_PIN_STATE: %d\n",
615                                 __func__, val);
616                 if (val)
617                         val = 0x08; /* 3:3=soft trigger */
618                 err = tps61050_i2c_rd(info, TPS61050_REG1, &reg);
619                 val |= reg;
620                 err |= tps61050_i2c_wr(info, TPS61050_REG1, val);
621                 return err;
622
623         default:
624                 dev_err(&info->i2c_client->dev,
625                                 "%s unsupported parameter: %d\n",
626                                 __func__, params->param);
627                 return -EINVAL;
628         }
629 }
630
631 static int tps61050_param_wr(struct tps61050_info *info, long arg)
632 {
633         struct nvc_param params;
634         u8 val;
635         int err = 0;
636
637         if (copy_from_user(&params, (const void __user *)arg,
638                            sizeof(struct nvc_param))) {
639                 dev_err(&info->i2c_client->dev, "%s %d copy_from_user err\n",
640                                 __func__, __LINE__);
641                 return -EINVAL;
642         }
643
644         if (copy_from_user(&val, (const void __user *)params.p_value,
645                            sizeof(val))) {
646                 dev_err(&info->i2c_client->dev, "%s %d copy_from_user err\n",
647                                 __func__, __LINE__);
648                 return -EINVAL;
649         }
650
651         /* parameters independent of sync mode */
652         switch (params.param) {
653         case NVC_PARAM_STEREO:
654                 dev_dbg(&info->i2c_client->dev, "%s STEREO: %d\n",
655                                 __func__, (int)val);
656                 if (val == info->s_mode)
657                         return 0;
658
659                 switch (val) {
660                 case NVC_SYNC_OFF:
661                         info->s_mode = val;
662                         if (info->s_info != NULL) {
663                                 info->s_info->s_mode = val;
664                                 tps61050_pm_wr(info->s_info, NVC_PWR_OFF);
665                         }
666                         break;
667
668                 case NVC_SYNC_MASTER:
669                         info->s_mode = val;
670                         if (info->s_info != NULL)
671                                 info->s_info->s_mode = val;
672                         break;
673
674                 case NVC_SYNC_SLAVE:
675                 case NVC_SYNC_STEREO:
676                         if (info->s_info != NULL) {
677                                 /* sync power */
678                                 info->s_info->pwr_api = info->pwr_api;
679                                 err = tps61050_pm_wr(info->s_info,
680                                                      info->pwr_dev);
681                                 if (!err) {
682                                         info->s_mode = val;
683                                         info->s_info->s_mode = val;
684                                 } else {
685                                         tps61050_pm_wr(info->s_info,
686                                                        NVC_PWR_OFF);
687                                         err = -EIO;
688                                 }
689                         } else {
690                                 err = -EINVAL;
691                         }
692                         break;
693
694                 default:
695                         err = -EINVAL;
696                 }
697                 if (info->pdata->cfg & NVC_CFG_NOERR)
698                         return 0;
699
700                 return err;
701
702         default:
703         /* parameters dependent on sync mode */
704                 switch (info->s_mode) {
705                 case NVC_SYNC_OFF:
706                 case NVC_SYNC_MASTER:
707                         return tps61050_param_wr_s(info, &params, val);
708
709                 case NVC_SYNC_SLAVE:
710                         return tps61050_param_wr_s(info->s_info,
711                                                  &params,
712                                                  val);
713
714                 case NVC_SYNC_STEREO:
715                         err = tps61050_param_wr_s(info, &params, val);
716                         if (!(info->pdata->cfg & NVC_CFG_SYNC_I2C_MUX))
717                                 err |= tps61050_param_wr_s(info->s_info,
718                                                          &params,
719                                                          val);
720                         return err;
721
722                 default:
723                         dev_err(&info->i2c_client->dev, "%s %d internal err\n",
724                                         __func__, __LINE__);
725                         return -EINVAL;
726                 }
727         }
728 }
729
730 static long tps61050_ioctl(struct file *file,
731                 unsigned int cmd,
732                 unsigned long arg)
733 {
734         struct tps61050_info *info = file->private_data;
735         int pwr;
736
737         switch (cmd) {
738         case NVC_IOCTL_PARAM_WR:
739                 return tps61050_param_wr(info, arg);
740
741         case NVC_IOCTL_PARAM_RD:
742                 return tps61050_param_rd(info, arg);
743
744         case NVC_IOCTL_PWR_WR:
745                 /* This is a Guaranteed Level of Service (GLOS) call */
746                 pwr = (int)arg * 2;
747                 dev_dbg(&info->i2c_client->dev, "%s PWR_WR: %d\n",
748                                 __func__, pwr);
749                 return tps61050_pm_api_wr(info, pwr);
750
751         case NVC_IOCTL_PWR_RD:
752                 if (info->s_mode == NVC_SYNC_SLAVE)
753                         pwr = info->s_info->pwr_api / 2;
754                 else
755                         pwr = info->pwr_api / 2;
756                 dev_dbg(&info->i2c_client->dev, "%s PWR_RD: %d\n",
757                                 __func__, pwr);
758                 if (copy_to_user((void __user *)arg, (const void *)&pwr,
759                                  sizeof(pwr))) {
760                         dev_err(&info->i2c_client->dev,
761                                         "%s copy_to_user err line %d\n",
762                                         __func__, __LINE__);
763                         return -EFAULT;
764                 }
765                 return 0;
766
767         default:
768                 dev_err(&info->i2c_client->dev, "%s unsupported ioctl: %x\n",
769                                 __func__, cmd);
770                 return -EINVAL;
771         }
772 }
773
774 static int tps61050_sync_en(int dev1, int dev2)
775 {
776         struct tps61050_info *sync1 = NULL;
777         struct tps61050_info *sync2 = NULL;
778         struct tps61050_info *pos = NULL;
779
780         rcu_read_lock();
781         list_for_each_entry_rcu(pos, &tps61050_info_list, list) {
782                 if (pos->pdata->num == dev1) {
783                         sync1 = pos;
784                         break;
785                 }
786         }
787         pos = NULL;
788         list_for_each_entry_rcu(pos, &tps61050_info_list, list) {
789                 if (pos->pdata->num == dev2) {
790                         sync2 = pos;
791                         break;
792                 }
793         }
794         rcu_read_unlock();
795         if (sync1 != NULL)
796                 sync1->s_info = NULL;
797         if (sync2 != NULL)
798                 sync2->s_info = NULL;
799         if (!dev1 && !dev2)
800                 return 0; /* no err if default instance 0's used */
801
802         if (dev1 == dev2)
803                 return -EINVAL; /* err if sync instance is itself */
804
805         if ((sync1 != NULL) && (sync2 != NULL)) {
806                 sync1->s_info = sync2;
807                 sync2->s_info = sync1;
808         }
809         return 0;
810 }
811
812 static int tps61050_sync_dis(struct tps61050_info *info)
813 {
814         if (info->s_info != NULL) {
815                 info->s_info->s_mode = 0;
816                 info->s_info->s_info = NULL;
817                 info->s_mode = 0;
818                 info->s_info = NULL;
819                 return 0;
820         }
821
822         return -EINVAL;
823 }
824
825 static int tps61050_open(struct inode *inode, struct file *file)
826 {
827         struct tps61050_info *info = NULL;
828         struct tps61050_info *pos = NULL;
829         int err;
830
831         rcu_read_lock();
832         list_for_each_entry_rcu(pos, &tps61050_info_list, list) {
833                 if (pos->miscdev.minor == iminor(inode)) {
834                         info = pos;
835                         break;
836                 }
837         }
838         rcu_read_unlock();
839         if (!info)
840                 return -ENODEV;
841
842         err = tps61050_sync_en(info->pdata->num, info->pdata->sync);
843         if (err == -EINVAL)
844                 dev_err(&info->i2c_client->dev,
845                          "%s err: invalid num (%u) and sync (%u) instance\n",
846                          __func__, info->pdata->num, info->pdata->sync);
847         if (atomic_xchg(&info->in_use, 1))
848                 return -EBUSY;
849
850         if (info->s_info != NULL) {
851                 if (atomic_xchg(&info->s_info->in_use, 1))
852                         return -EBUSY;
853         }
854
855         file->private_data = info;
856         dev_dbg(&info->i2c_client->dev, "%s\n", __func__);
857         return 0;
858 }
859
860 static int tps61050_release(struct inode *inode, struct file *file)
861 {
862         struct tps61050_info *info = file->private_data;
863
864         dev_dbg(&info->i2c_client->dev, "%s\n", __func__);
865         tps61050_pm_wr_s(info, NVC_PWR_OFF);
866         file->private_data = NULL;
867         WARN_ON(!atomic_xchg(&info->in_use, 0));
868         if (info->s_info != NULL)
869                 WARN_ON(!atomic_xchg(&info->s_info->in_use, 0));
870         tps61050_sync_dis(info);
871         return 0;
872 }
873
874 static const struct file_operations tps61050_fileops = {
875         .owner = THIS_MODULE,
876         .open = tps61050_open,
877         .unlocked_ioctl = tps61050_ioctl,
878         .release = tps61050_release,
879 };
880
881 static void tps61050_del(struct tps61050_info *info)
882 {
883         tps61050_pm_exit(info);
884         tps61050_sync_dis(info);
885         spin_lock(&tps61050_spinlock);
886         list_del_rcu(&info->list);
887         spin_unlock(&tps61050_spinlock);
888         synchronize_rcu();
889 }
890
891 static int tps61050_remove(struct i2c_client *client)
892 {
893         struct tps61050_info *info = i2c_get_clientdata(client);
894
895         dev_dbg(&info->i2c_client->dev, "%s\n", __func__);
896         misc_deregister(&info->miscdev);
897         tps61050_del(info);
898         return 0;
899 }
900
901 static int tps61050_probe(
902         struct i2c_client *client,
903         const struct i2c_device_id *id)
904 {
905         struct tps61050_info *info;
906         char dname[16];
907         int err;
908
909         dev_dbg(&client->dev, "%s\n", __func__);
910         info = devm_kzalloc(&client->dev, sizeof(*info), GFP_KERNEL);
911         if (info == NULL) {
912                 dev_err(&client->dev, "%s: kzalloc error\n", __func__);
913                 return -ENOMEM;
914         }
915
916         info->i2c_client = client;
917         if (client->dev.platform_data) {
918                 info->pdata = client->dev.platform_data;
919         } else {
920                 info->pdata = &tps61050_default_pdata;
921                 dev_dbg(&client->dev,
922                         "%s No platform data.  Using defaults.\n",
923                         __func__);
924         }
925         i2c_set_clientdata(client, info);
926         INIT_LIST_HEAD(&info->list);
927         spin_lock(&tps61050_spinlock);
928         list_add_rcu(&info->list, &tps61050_info_list);
929         spin_unlock(&tps61050_spinlock);
930         tps61050_pm_init(info);
931         err = tps61050_dev_id(info);
932         if (err < 0) {
933                 dev_err(&client->dev, "%s device not found\n", __func__);
934                 if (info->pdata->cfg & NVC_CFG_NODEV) {
935                         tps61050_del(info);
936                         return -ENODEV;
937                 }
938         } else {
939                 dev_dbg(&client->dev, "%s device found\n", __func__);
940         }
941
942         if (info->pdata->dev_name != 0)
943                 strcpy(dname, info->pdata->dev_name);
944         else
945                 strcpy(dname, "tps61050");
946         if (info->pdata->num)
947                 snprintf(dname, sizeof(dname), "%s.%u",
948                          dname, info->pdata->num);
949         info->miscdev.name = dname;
950         info->miscdev.fops = &tps61050_fileops;
951         info->miscdev.minor = MISC_DYNAMIC_MINOR;
952         if (misc_register(&info->miscdev)) {
953                 dev_err(&client->dev, "%s unable to register misc device %s\n",
954                                 __func__, dname);
955                 tps61050_del(info);
956                 return -ENODEV;
957         }
958
959         return 0;
960 }
961
962 static const struct i2c_device_id tps61050_id[] = {
963         { "tps61050", 0 },
964         { },
965 };
966
967 MODULE_DEVICE_TABLE(i2c, tps61050_id);
968
969 static struct i2c_driver tps61050_i2c_driver = {
970         .driver = {
971                 .name = "tps61050",
972                 .owner = THIS_MODULE,
973         },
974         .id_table = tps61050_id,
975         .probe = tps61050_probe,
976         .remove = tps61050_remove,
977 };
978
979 static int __init tps61050_init(void)
980 {
981         return i2c_add_driver(&tps61050_i2c_driver);
982 }
983
984 static void __exit tps61050_exit(void)
985 {
986         i2c_del_driver(&tps61050_i2c_driver);
987 }
988
989 module_init(tps61050_init);
990 module_exit(tps61050_exit);
991 MODULE_LICENSE("GPL");