Merge branch 'android-tegra-2.6.36' into android-tegra-moto-2.6.36
[firefly-linux-kernel-4.4.55.git] / drivers / mfd / cpcap-uc.c
1 /*
2  * Copyright (C) 2008-2010 Motorola, Inc.
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
16  * 02111-1307, USA
17  */
18
19 #include <linux/completion.h>
20 #include <linux/errno.h>
21 #include <linux/firmware.h>
22 #include <linux/fs.h>
23 #include <linux/ihex.h>
24 #include <linux/miscdevice.h>
25 #include <linux/mutex.h>
26 #include <linux/platform_device.h>
27 #include <linux/uaccess.h>
28
29 #include <linux/spi/cpcap.h>
30 #include <linux/spi/cpcap-regbits.h>
31 #include <linux/spi/spi.h>
32
33
34 #define ERROR_MACRO_TIMEOUT  0x81
35 #define ERROR_MACRO_WRITE    0x82
36 #define ERROR_MACRO_READ     0x83
37
38 #define RAM_START_TI         0x9000
39 #define RAM_END_TI           0x9FA0
40 #define RAM_START_ST         0x0000
41 #define RAM_END_ST           0x0FFF
42
43 #define HWCFG_ADDR_ST        0x0122
44
45 enum {
46         READ_STATE_1,   /* Send size and location of RAM read. */
47         READ_STATE_2,   /*!< Read MT registers. */
48         READ_STATE_3,   /*!< Read data from uC. */
49         READ_STATE_4,   /*!< Check for error. */
50 };
51
52 enum {
53         WRITE_STATE_1,  /* Send size and location of RAM write. */
54         WRITE_STATE_2,  /* Check for error. */
55         WRITE_STATE_3,  /* Write data to uC. */
56         WRITE_STATE_4   /* Check for error. */
57 };
58
59 struct cpcap_uc_data {
60         struct cpcap_device *cpcap;
61         unsigned char is_supported;
62         unsigned char is_ready;
63         struct completion completion;
64         int cb_status;
65         struct mutex lock;
66         unsigned char uc_reset;
67         unsigned char state;
68         unsigned short state_cntr;
69         struct {
70                 unsigned short address;
71                 unsigned short *data;
72                 unsigned short num_words;
73         } req;
74 };
75
76 static struct cpcap_uc_data *cpcap_uc_info;
77
78 static int fops_open(struct inode *inode, struct file *file);
79 static long fops_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
80 static ssize_t fops_write(struct file *file, const char *buf,
81                           size_t count, loff_t *ppos);
82 static ssize_t fops_read(struct file *file, char *buf,
83                          size_t count, loff_t *ppos);
84
85
86 static const struct file_operations fops = {
87         .owner = THIS_MODULE,
88         .unlocked_ioctl = fops_ioctl,
89         .open = fops_open,
90         .read = fops_read,
91         .write = fops_write,
92 };
93
94 static struct miscdevice uc_dev = {
95         .minor = MISC_DYNAMIC_MINOR,
96         .name = "cpcap_uc",
97         .fops = &fops,
98 };
99
100 static int is_valid_address(struct cpcap_device *cpcap, unsigned short address,
101                             unsigned short num_words)
102 {
103         int vld = 0;
104
105         if (cpcap->vendor == CPCAP_VENDOR_TI) {
106                 vld = (address >= RAM_START_TI) &&
107                     ((address + num_words) <= RAM_END_TI);
108         } else if (cpcap->vendor == CPCAP_VENDOR_ST) {
109                 vld = ((address + num_words) <= RAM_END_ST);
110         }
111
112         return vld;
113 }
114
115 static void ram_read_state_machine(enum cpcap_irqs irq, void *data)
116 {
117         struct cpcap_uc_data *uc_data = data;
118         unsigned short temp;
119
120         if (irq != CPCAP_IRQ_UC_PRIRAMR)
121                 return;
122
123         switch (uc_data->state) {
124         case READ_STATE_1:
125                 cpcap_regacc_write(uc_data->cpcap, CPCAP_REG_MT1,
126                                    uc_data->req.address, 0xFFFF);
127                 cpcap_regacc_write(uc_data->cpcap, CPCAP_REG_MT2,
128                                    uc_data->req.num_words, 0xFFFF);
129                 cpcap_regacc_write(uc_data->cpcap, CPCAP_REG_MT3, 0, 0xFFFF);
130
131                 if (uc_data->cpcap->vendor == CPCAP_VENDOR_ST)
132                         uc_data->state = READ_STATE_2;
133                 else
134                         uc_data->state = READ_STATE_3;
135
136                 cpcap_irq_unmask(uc_data->cpcap, CPCAP_IRQ_UC_PRIRAMR);
137                 break;
138
139         case READ_STATE_2:
140                 cpcap_regacc_read(uc_data->cpcap, CPCAP_REG_MT1, &temp);
141
142                 if (temp == ERROR_MACRO_READ) {
143                         uc_data->state = READ_STATE_1;
144                         uc_data->state_cntr = 0;
145
146                         cpcap_irq_mask(uc_data->cpcap, CPCAP_IRQ_UC_PRIRAMR);
147
148                         uc_data->cb_status = -EIO;
149
150                         complete(&uc_data->completion);
151                 } else {
152                         cpcap_regacc_read(uc_data->cpcap, CPCAP_REG_MT2, &temp);
153                         cpcap_regacc_read(uc_data->cpcap, CPCAP_REG_MT3, &temp);
154
155                         uc_data->state = READ_STATE_3;
156                         cpcap_irq_unmask(uc_data->cpcap, CPCAP_IRQ_UC_PRIRAMR);
157                 }
158                 break;
159
160         case READ_STATE_3:
161                 cpcap_regacc_read(uc_data->cpcap, CPCAP_REG_MT1,
162                                   uc_data->req.data + uc_data->state_cntr);
163
164                 uc_data->state_cntr += 1;
165
166                 if (uc_data->state_cntr == uc_data->req.num_words)
167                         cpcap_regacc_read(uc_data->cpcap, CPCAP_REG_MT2, &temp);
168                 else {
169                         cpcap_regacc_read(uc_data->cpcap, CPCAP_REG_MT2,
170                                           uc_data->req.data +
171                                           uc_data->state_cntr);
172
173                         uc_data->state_cntr += 1;
174                 }
175
176                 if (uc_data->state_cntr == uc_data->req.num_words)
177                         cpcap_regacc_read(uc_data->cpcap, CPCAP_REG_MT3, &temp);
178                 else {
179                         cpcap_regacc_read(uc_data->cpcap, CPCAP_REG_MT3,
180                                           uc_data->req.data +
181                                           uc_data->state_cntr);
182
183                         uc_data->state_cntr += 1;
184                 }
185
186                 if (uc_data->state_cntr == uc_data->req.num_words)
187                         uc_data->state = READ_STATE_4;
188
189                 cpcap_irq_unmask(uc_data->cpcap, CPCAP_IRQ_UC_PRIRAMR);
190                 break;
191
192         case READ_STATE_4:
193                 cpcap_regacc_read(uc_data->cpcap, CPCAP_REG_MT1, &temp);
194
195                 if (temp != ERROR_MACRO_READ)
196                         uc_data->cb_status = 0;
197                 else
198                         uc_data->cb_status = -EIO;
199
200                 complete(&uc_data->completion);
201
202                 uc_data->state = READ_STATE_1;
203                 uc_data->state_cntr = 0;
204                 break;
205
206         default:
207                 uc_data->state = READ_STATE_1;
208                 uc_data->state_cntr = 0;
209                 break;
210         }
211 }
212
213 static void ram_write_state_machine(enum cpcap_irqs irq, void *data)
214 {
215         struct cpcap_uc_data *uc_data = data;
216         unsigned short error_check;
217
218         if (irq != CPCAP_IRQ_UC_PRIRAMW)
219                 return;
220
221         switch (uc_data->state) {
222         case WRITE_STATE_1:
223                 cpcap_regacc_write(uc_data->cpcap, CPCAP_REG_MT1,
224                                    uc_data->req.address, 0xFFFF);
225                 cpcap_regacc_write(uc_data->cpcap, CPCAP_REG_MT2,
226                                    uc_data->req.num_words, 0xFFFF);
227                 cpcap_regacc_write(uc_data->cpcap, CPCAP_REG_MT3, 0, 0xFFFF);
228
229                 uc_data->state = WRITE_STATE_2;
230                 cpcap_irq_unmask(uc_data->cpcap, CPCAP_IRQ_UC_PRIRAMW);
231                 break;
232
233         case WRITE_STATE_2:
234                 cpcap_regacc_read(uc_data->cpcap, CPCAP_REG_MT1, &error_check);
235
236                 if (error_check == ERROR_MACRO_WRITE) {
237                         uc_data->state = WRITE_STATE_1;
238                         uc_data->state_cntr = 0;
239
240                         cpcap_irq_mask(uc_data->cpcap,
241                                        CPCAP_IRQ_UC_PRIRAMW);
242
243                         uc_data->cb_status = -EIO;
244                         complete(&uc_data->completion);
245                         break;
246                 } else
247                         uc_data->state = WRITE_STATE_3;
248
249                 /* No error has occured, fall through */
250
251         case WRITE_STATE_3:
252                 cpcap_regacc_write(uc_data->cpcap, CPCAP_REG_MT1,
253                                    *(uc_data->req.data + uc_data->state_cntr),
254                                    0xFFFF);
255                 uc_data->state_cntr += 1;
256
257                 if (uc_data->state_cntr == uc_data->req.num_words)
258                         cpcap_regacc_write(uc_data->cpcap, CPCAP_REG_MT2, 0,
259                                            0xFFFF);
260                 else {
261                         cpcap_regacc_write(uc_data->cpcap, CPCAP_REG_MT2,
262                                            *(uc_data->req.data +
263                                              uc_data->state_cntr), 0xFFFF);
264
265                         uc_data->state_cntr += 1;
266                 }
267
268                 if (uc_data->state_cntr == uc_data->req.num_words)
269                         cpcap_regacc_write(uc_data->cpcap, CPCAP_REG_MT3, 0,
270                                            0xFFFF);
271                 else {
272                         cpcap_regacc_write(uc_data->cpcap, CPCAP_REG_MT3,
273                                            *(uc_data->req.data +
274                                              uc_data->state_cntr), 0xFFFF);
275
276                         uc_data->state_cntr += 1;
277                 }
278
279                 if (uc_data->state_cntr == uc_data->req.num_words)
280                         uc_data->state = WRITE_STATE_4;
281
282                 cpcap_irq_unmask(uc_data->cpcap, CPCAP_IRQ_UC_PRIRAMW);
283                 break;
284
285         case WRITE_STATE_4:
286                 cpcap_regacc_read(uc_data->cpcap, CPCAP_REG_MT1, &error_check);
287
288                 if (error_check != ERROR_MACRO_WRITE)
289                         uc_data->cb_status = 0;
290                 else
291                         uc_data->cb_status = -EIO;
292
293                 complete(&uc_data->completion);
294
295                 uc_data->state = WRITE_STATE_1;
296                 uc_data->state_cntr = 0;
297                 break;
298
299         default:
300                 uc_data->state = WRITE_STATE_1;
301                 uc_data->state_cntr = 0;
302                 break;
303         }
304 }
305
306 static void reset_handler(enum cpcap_irqs irq, void *data)
307 {
308         int i;
309         unsigned short regval;
310         struct cpcap_uc_data *uc_data = data;
311
312         if (irq != CPCAP_IRQ_UCRESET)
313                 return;
314
315         cpcap_regacc_write(uc_data->cpcap, CPCAP_REG_UCC1,
316                            CPCAP_BIT_PRIHALT, CPCAP_BIT_PRIHALT);
317
318         cpcap_regacc_write(uc_data->cpcap, CPCAP_REG_PGC,
319                            CPCAP_BIT_PRI_UC_SUSPEND, CPCAP_BIT_PRI_UC_SUSPEND);
320
321         uc_data->uc_reset = 1;
322         uc_data->cb_status = -EIO;
323         complete(&uc_data->completion);
324
325         cpcap_regacc_write(uc_data->cpcap, CPCAP_REG_MI2, 0, 0xFFFF);
326         cpcap_regacc_write(uc_data->cpcap, CPCAP_REG_MIM1, 0xFFFF, 0xFFFF);
327         cpcap_irq_mask(uc_data->cpcap, CPCAP_IRQ_PRIMAC);
328         cpcap_irq_unmask(uc_data->cpcap, CPCAP_IRQ_UCRESET);
329
330         for (i = 0; i <= CPCAP_REG_END; i++) {
331                 cpcap_regacc_read(uc_data->cpcap, i, &regval);
332                 dev_err(&uc_data->cpcap->spi->dev,
333                         "cpcap reg %d = 0x%04X\n", i, regval);
334         }
335
336         BUG();
337 }
338
339 static void primac_handler(enum cpcap_irqs irq, void *data)
340 {
341         struct cpcap_uc_data *uc_data = data;
342
343         if (irq == CPCAP_IRQ_PRIMAC)
344                 cpcap_irq_unmask(uc_data->cpcap, CPCAP_IRQ_PRIMAC);
345 }
346
347 static int ram_write(struct cpcap_uc_data *uc_data, unsigned short address,
348                      unsigned short num_words, unsigned short *data)
349 {
350         int retval = -EFAULT;
351
352         mutex_lock(&uc_data->lock);
353
354         if ((uc_data->cpcap->vendor == CPCAP_VENDOR_ST) &&
355             (uc_data->cpcap->revision <= CPCAP_REVISION_2_0)) {
356                 cpcap_regacc_write(uc_data->cpcap, CPCAP_REG_UCTM,
357                                    CPCAP_BIT_UCTM, CPCAP_BIT_UCTM);
358         }
359
360         if (uc_data->is_supported && (num_words > 0) &&
361                 (data != NULL) &&
362                 is_valid_address(uc_data->cpcap, address, num_words) &&
363             !uc_data->uc_reset) {
364                 uc_data->req.address = address;
365                 uc_data->req.data = data;
366                 uc_data->req.num_words = num_words;
367                 uc_data->state = WRITE_STATE_1;
368                 uc_data->state_cntr = 0;
369                 INIT_COMPLETION(uc_data->completion);
370
371                 retval = cpcap_regacc_write(uc_data->cpcap, CPCAP_REG_MI2,
372                                         CPCAP_BIT_PRIRAMW,
373                                         CPCAP_BIT_PRIRAMW);
374                 if (retval)
375                         goto err;
376
377                 /* Cannot call cpcap_irq_register() here because unregister
378                  * cannot be called from the state machine. Doing so causes
379                  * a deadlock. */
380                 retval = cpcap_irq_unmask(uc_data->cpcap, CPCAP_IRQ_UC_PRIRAMW);
381                 if (retval)
382                         goto err;
383
384                 wait_for_completion(&uc_data->completion);
385                 retval = uc_data->cb_status;
386         }
387
388 err:
389         if ((uc_data->cpcap->vendor == CPCAP_VENDOR_ST) &&
390             (uc_data->cpcap->revision <= CPCAP_REVISION_2_0)) {
391                 cpcap_regacc_write(uc_data->cpcap, CPCAP_REG_UCTM,
392                                    0, CPCAP_BIT_UCTM);
393         }
394
395         mutex_unlock(&uc_data->lock);
396         return retval;
397 }
398
399 static int ram_read(struct cpcap_uc_data *uc_data, unsigned short address,
400                     unsigned short num_words, unsigned short *data)
401 {
402         int retval = -EFAULT;
403
404         mutex_lock(&uc_data->lock);
405
406         if ((uc_data->cpcap->vendor == CPCAP_VENDOR_ST) &&
407             (uc_data->cpcap->revision <= CPCAP_REVISION_2_0)) {
408                 cpcap_regacc_write(uc_data->cpcap, CPCAP_REG_UCTM,
409                                    CPCAP_BIT_UCTM, CPCAP_BIT_UCTM);
410         }
411
412         if (uc_data->is_supported && (num_words > 0) &&
413             is_valid_address(uc_data->cpcap, address, num_words) &&
414                 !uc_data->uc_reset) {
415                 uc_data->req.address = address;
416                 uc_data->req.data = data;
417                 uc_data->req.num_words = num_words;
418                 uc_data->state = READ_STATE_1;
419                 uc_data->state_cntr = 0;
420                 INIT_COMPLETION(uc_data->completion);
421
422                 retval = cpcap_regacc_write(uc_data->cpcap, CPCAP_REG_MI2,
423                                             CPCAP_BIT_PRIRAMR,
424                                             CPCAP_BIT_PRIRAMR);
425                 if (retval)
426                         goto err;
427
428                 /* Cannot call cpcap_irq_register() here because unregister
429                  * cannot be called from the state machine. Doing so causes
430                  * a deadlock. */
431                 retval = cpcap_irq_unmask(uc_data->cpcap, CPCAP_IRQ_UC_PRIRAMR);
432                 if (retval)
433                         goto err;
434
435                 wait_for_completion(&uc_data->completion);
436                 retval = uc_data->cb_status;
437         }
438
439 err:
440         if ((uc_data->cpcap->vendor == CPCAP_VENDOR_ST) &&
441             (uc_data->cpcap->revision <= CPCAP_REVISION_2_0)) {
442                 cpcap_regacc_write(uc_data->cpcap, CPCAP_REG_UCTM,
443                                    0, CPCAP_BIT_UCTM);
444         }
445
446         mutex_unlock(&uc_data->lock);
447         return retval;
448 }
449
450 static int ram_load(struct cpcap_uc_data *uc_data, unsigned int num_words,
451                     unsigned short *data)
452 {
453         int retval = -EINVAL;
454
455         if ((data != NULL) && (num_words > 0))
456                 retval = ram_write(uc_data, data[0], (num_words - 1),
457                                    (data + 1));
458
459         return retval;
460 }
461
462 static ssize_t fops_write(struct file *file, const char *buf,
463                           size_t count, loff_t *ppos)
464 {
465         ssize_t retval = -EINVAL;
466         unsigned short address;
467         unsigned short num_words;
468         unsigned short *data;
469         struct cpcap_uc_data *uc_data = file->private_data;
470
471         if ((buf != NULL) && (ppos != NULL) && (count >= 2)) {
472                 data = kzalloc(count, GFP_KERNEL);
473
474                 if (data != NULL) {
475                         num_words = (unsigned short) (count >> 1);
476
477                         /* If the position (uC RAM address) is zero then the
478                          * data contains the address */
479                         if (*ppos == 0) {
480                                 if (copy_from_user((void *) data, (void *) buf,
481                                                    count) == 0)
482                                         retval = ram_load(uc_data, num_words,
483                                                           data);
484                                 else
485                                         retval = -EFAULT;
486                         }
487                         /* If the position (uC RAM address) is not zero then the
488                          * position holds the address to load the data */
489                         else {
490                                 address = (unsigned short) (*ppos);
491
492                                 if (copy_from_user((void *) data, (void *) buf,
493                                                    count) == 0)
494                                         retval = ram_write(uc_data, address,
495                                                            num_words, data);
496                                 else
497                                         retval = -EFAULT;
498                         }
499
500                         kfree(data);
501                 } else {
502                         retval = -ENOMEM;
503                 }
504         }
505
506         if (retval == 0)
507                 retval = num_words;
508
509         return retval;
510 }
511
512 static ssize_t fops_read(struct file *file, char *buf,
513                          size_t count, loff_t *ppos)
514 {
515         ssize_t retval = -EFAULT;
516         unsigned short address;
517         unsigned short num_words;
518         unsigned short *data;
519         struct cpcap_uc_data *uc_data = file->private_data;
520
521         if ((buf != NULL) && (ppos != NULL) && (count >= 2)) {
522                 data = kzalloc(count, GFP_KERNEL);
523
524                 if (data != NULL) {
525                         address = (unsigned short) (*ppos);
526                         num_words = (unsigned short) (count >> 1);
527
528                         retval = ram_read(uc_data, address, num_words, data);
529                         if (retval)
530                                 goto err;
531
532                         if (copy_to_user((void *)buf, (void *)data, count) == 0)
533                                 retval = count;
534                         else
535                                 retval = -EFAULT;
536
537 err:
538                         kfree(data);
539                 } else {
540                         retval = -ENOMEM;
541                 }
542         }
543
544         return retval;
545 }
546
547 static long fops_ioctl(struct file *file, unsigned int cmd,
548                        unsigned long arg)
549 {
550         int retval = -ENOTTY;
551         struct cpcap_uc_data *data = file->private_data;
552
553         switch (cmd) {
554         case CPCAP_IOCTL_UC_MACRO_START:
555                 /* User space will only attempt to start the init macro if
556                  * the ram load requests complete successfully. This is used
557                  * as an indication that kernel requests to start macros can
558                  * be allowed.
559                  */
560                 data->is_ready = 1;
561
562                 retval = cpcap_uc_start(data->cpcap, (enum cpcap_macro)arg);
563
564                 break;
565
566         case CPCAP_IOCTL_UC_MACRO_STOP:
567                 retval = cpcap_uc_stop(data->cpcap, (enum cpcap_macro)arg);
568                 break;
569
570         case CPCAP_IOCTL_UC_GET_VENDOR:
571                 retval = copy_to_user((enum cpcap_vendor *)arg,
572                                         &(data->cpcap->vendor),
573                                         sizeof(enum cpcap_vendor));
574                 break;
575
576         case CPCAP_IOCTL_UC_SET_TURBO_MODE:
577                 if (arg != 0)
578                         arg = 1;
579                 retval = cpcap_regacc_write(data->cpcap, CPCAP_REG_UCTM,
580                                         (unsigned short)arg,
581                                         CPCAP_BIT_UCTM);
582                 break;
583
584         default:
585                 break;
586         }
587
588         return retval;
589 }
590
591 static int fops_open(struct inode *inode, struct file *file)
592 {
593         int retval = -ENOTTY;
594
595         if (cpcap_uc_info->is_supported)
596                 retval = 0;
597
598         file->private_data = cpcap_uc_info;
599         dev_info(&cpcap_uc_info->cpcap->spi->dev, "CPCAP uC: open status:%d\n",
600                  retval);
601
602         return retval;
603 }
604
605 int cpcap_uc_start(struct cpcap_device *cpcap, enum cpcap_macro macro)
606 {
607         int retval = -EFAULT;
608         struct cpcap_uc_data *data = cpcap->ucdata;
609
610         if ((data->is_ready) &&
611             (macro > CPCAP_MACRO_USEROFF) && (macro < CPCAP_MACRO__END) &&
612             (data->uc_reset == 0)) {
613                 if ((macro == CPCAP_MACRO_4) ||
614                     ((cpcap->vendor == CPCAP_VENDOR_ST) &&
615                      ((macro == CPCAP_MACRO_12) || (macro == CPCAP_MACRO_14) ||
616                       (macro == CPCAP_MACRO_15)))) {
617                         retval = cpcap_regacc_write(cpcap, CPCAP_REG_MI2,
618                                                     (1 << macro),
619                                                     (1 << macro));
620                 } else {
621                         retval = cpcap_regacc_write(cpcap, CPCAP_REG_MIM1,
622                                                     0, (1 << macro));
623                 }
624         }
625
626         return retval;
627 }
628 EXPORT_SYMBOL_GPL(cpcap_uc_start);
629
630 int cpcap_uc_stop(struct cpcap_device *cpcap, enum cpcap_macro macro)
631 {
632         int retval = -EFAULT;
633
634         if ((macro > CPCAP_MACRO_4) &&
635             (macro < CPCAP_MACRO__END)) {
636                 if ((cpcap->vendor == CPCAP_VENDOR_ST) &&
637                     ((macro == CPCAP_MACRO_12) || (macro == CPCAP_MACRO_14) ||
638                      (macro == CPCAP_MACRO_15))) {
639                         retval = cpcap_regacc_write(cpcap, CPCAP_REG_MI2,
640                                                     0, (1 << macro));
641                 } else {
642                         retval = cpcap_regacc_write(cpcap, CPCAP_REG_MIM1,
643                                                     (1 << macro), (1 << macro));
644                 }
645         }
646
647         return retval;
648 }
649 EXPORT_SYMBOL_GPL(cpcap_uc_stop);
650
651 unsigned char cpcap_uc_status(struct cpcap_device *cpcap,
652                               enum cpcap_macro macro)
653 {
654         unsigned char retval = 0;
655         unsigned short regval;
656
657         if (macro < CPCAP_MACRO__END) {
658                 if ((macro <= CPCAP_MACRO_4) ||
659                     ((cpcap->vendor == CPCAP_VENDOR_ST) &&
660                      ((macro == CPCAP_MACRO_12) || (macro == CPCAP_MACRO_14) ||
661                       (macro == CPCAP_MACRO_15)))) {
662                         cpcap_regacc_read(cpcap, CPCAP_REG_MI2, &regval);
663
664                         if (regval & (1 << macro))
665                                 retval = 1;
666                 } else {
667                         cpcap_regacc_read(cpcap, CPCAP_REG_MIM1, &regval);
668
669                         if (!(regval & (1 << macro)))
670                                 retval = 1;
671                 }
672         }
673
674         return retval;
675 }
676 EXPORT_SYMBOL_GPL(cpcap_uc_status);
677
678 static int fw_load(struct cpcap_uc_data *uc_data, struct device *dev)
679 {
680         int err;
681         const struct ihex_binrec *rec;
682         const struct firmware *fw;
683         unsigned short *buf;
684         int i;
685         unsigned short num_bytes;
686         unsigned short num_words;
687         unsigned char odd_bytes;
688         struct cpcap_platform_data *data;
689
690         data = uc_data->cpcap->spi->controller_data;
691
692         if (!uc_data || !dev)
693                 return -EINVAL;
694
695         if (uc_data->cpcap->vendor == CPCAP_VENDOR_ST)
696                 err = request_ihex_firmware(&fw, "cpcap/firmware_0_2x.fw", dev);
697         else
698                 err = request_ihex_firmware(&fw, "cpcap/firmware_1_2x.fw", dev);
699
700         if (err) {
701                 dev_err(dev, "Failed to load \"cpcap/firmware_%d_2x.fw\": %d\n",
702                         uc_data->cpcap->vendor, err);
703                 goto err;
704         }
705
706         for (rec = (void *)fw->data; rec; rec = ihex_next_binrec(rec)) {
707                 odd_bytes = 0;
708                 num_bytes = be16_to_cpu(rec->len);
709
710                 /* Since loader requires words, need even number of bytes. */
711                 if (be16_to_cpu(rec->len) % 2) {
712                         num_bytes++;
713                         odd_bytes = 1;
714                 }
715
716                 num_words = num_bytes >> 1;
717                 dev_info(dev, "Loading %d word(s) at 0x%04x\n",
718                          num_words, be32_to_cpu(rec->addr));
719
720                 buf = kzalloc(num_bytes, GFP_KERNEL);
721                 if (buf) {
722                         for (i = 0; i < num_words; i++) {
723                                 if (odd_bytes && (i == (num_words - 1)))
724                                         buf[i] = rec->data[i * 2];
725                                 else
726                                         buf[i] = ((uint16_t *)rec->data)[i];
727
728                                 buf[i] = be16_to_cpu(buf[i]);
729                         }
730
731                         err = ram_write(uc_data, be32_to_cpu(rec->addr),
732                                         num_words, buf);
733                         kfree(buf);
734
735                         if (err) {
736                                 dev_err(dev, "RAM write failed: %d\n", err);
737                                 break;
738                         }
739                 } else {
740                         err = -ENOMEM;
741                         dev_err(dev, "RAM write failed: %d\n", err);
742                         break;
743                 }
744         }
745
746         release_firmware(fw);
747
748         if (!err) {
749                 uc_data->is_ready = 1;
750
751                 if (uc_data->cpcap->vendor == CPCAP_VENDOR_ST) {
752                         err = ram_write(uc_data, HWCFG_ADDR_ST, CPCAP_HWCFG_NUM,
753                                         data->hwcfg);
754                         dev_info(dev, "Loaded HWCFG data: %d\n", err);
755                 }
756
757                 err = cpcap_uc_start(uc_data->cpcap, CPCAP_MACRO_4);
758                 dev_info(dev, "Started macro 4: %d\n", err);
759         }
760
761 err:
762         return err;
763 }
764
765 static int cpcap_uc_probe(struct platform_device *pdev)
766 {
767         int retval = 0;
768         struct cpcap_uc_data *data;
769
770         if (pdev->dev.platform_data == NULL) {
771                 dev_err(&pdev->dev, "no platform_data\n");
772                 return -EINVAL;
773         }
774
775         data = kzalloc(sizeof(*data), GFP_KERNEL);
776         if (!data)
777                 return -ENOMEM;
778
779         data->cpcap = pdev->dev.platform_data;
780         data->uc_reset = 0;
781         data->is_supported = 0;
782         data->req.address = 0;
783         data->req.data = NULL;
784         data->req.num_words = 0;
785
786         init_completion(&data->completion);
787         mutex_init(&data->lock);
788         platform_set_drvdata(pdev, data);
789         cpcap_uc_info = data;
790         data->cpcap->ucdata = data;
791
792         if (((data->cpcap->vendor == CPCAP_VENDOR_TI) &&
793              (data->cpcap->revision >= CPCAP_REVISION_2_0)) ||
794                 (data->cpcap->vendor == CPCAP_VENDOR_ST)) {
795                 retval = cpcap_irq_register(data->cpcap, CPCAP_IRQ_PRIMAC,
796                                             primac_handler, data);
797                 if (retval)
798                         goto err_free;
799
800                 cpcap_irq_clear(data->cpcap, CPCAP_IRQ_UCRESET);
801                 retval = cpcap_irq_register(data->cpcap, CPCAP_IRQ_UCRESET,
802                                             reset_handler, data);
803                 if (retval)
804                         goto err_primac;
805
806                 retval = cpcap_irq_register(data->cpcap,
807                                             CPCAP_IRQ_UC_PRIRAMR,
808                                             ram_read_state_machine, data);
809                 if (retval)
810                         goto err_ucreset;
811
812                 retval = cpcap_irq_register(data->cpcap,
813                                             CPCAP_IRQ_UC_PRIRAMW,
814                                             ram_write_state_machine, data);
815                 if (retval)
816                         goto err_priramr;
817
818                 retval = misc_register(&uc_dev);
819                 if (retval)
820                         goto err_priramw;
821
822                 data->is_supported = 1;
823
824                 cpcap_regacc_write(data->cpcap, CPCAP_REG_MIM1, 0xFFFF,
825                                    0xFFFF);
826
827                 retval = fw_load(data, &pdev->dev);
828                 if (retval)
829                         goto err_fw;
830         } else
831                 retval = -ENODEV;
832
833         return retval;
834
835 err_fw:
836         misc_deregister(&uc_dev);
837 err_priramw:
838         cpcap_irq_free(data->cpcap, CPCAP_IRQ_UC_PRIRAMW);
839 err_priramr:
840         cpcap_irq_free(data->cpcap, CPCAP_IRQ_UC_PRIRAMR);
841 err_ucreset:
842         cpcap_irq_free(data->cpcap, CPCAP_IRQ_UCRESET);
843 err_primac:
844         cpcap_irq_free(data->cpcap, CPCAP_IRQ_PRIMAC);
845 err_free:
846         kfree(data);
847
848         return retval;
849 }
850
851 static int __exit cpcap_uc_remove(struct platform_device *pdev)
852 {
853         struct cpcap_uc_data *data = platform_get_drvdata(pdev);
854
855         misc_deregister(&uc_dev);
856
857         cpcap_irq_free(data->cpcap, CPCAP_IRQ_PRIMAC);
858         cpcap_irq_free(data->cpcap, CPCAP_IRQ_UC_PRIRAMW);
859         cpcap_irq_free(data->cpcap, CPCAP_IRQ_UC_PRIRAMR);
860         cpcap_irq_free(data->cpcap, CPCAP_IRQ_UCRESET);
861
862         kfree(data);
863         return 0;
864 }
865
866
867 static struct platform_driver cpcap_uc_driver = {
868         .probe          = cpcap_uc_probe,
869         .remove         = __exit_p(cpcap_uc_remove),
870         .driver         = {
871                 .name   = "cpcap_uc",
872                 .owner  = THIS_MODULE,
873         },
874 };
875
876 static int __init cpcap_uc_init(void)
877 {
878         return platform_driver_register(&cpcap_uc_driver);
879 }
880 subsys_initcall(cpcap_uc_init);
881
882 static void __exit cpcap_uc_exit(void)
883 {
884         platform_driver_unregister(&cpcap_uc_driver);
885 }
886 module_exit(cpcap_uc_exit);
887
888 MODULE_ALIAS("platform:cpcap_uc");
889 MODULE_DESCRIPTION("CPCAP uC driver");
890 MODULE_AUTHOR("Motorola");
891 MODULE_LICENSE("GPL");
892 MODULE_FIRMWARE("cpcap/firmware_0_2x.fw");
893 MODULE_FIRMWARE("cpcap/firmware_1_2x.fw");