Merge branch 'develop' of lhh@10.10.10.201:/home/rockchip/rk2818/kernel into develop
[firefly-linux-kernel-4.4.55.git] / drivers / cmmb / siano / smsspiphy_rk.c
1 /****************************************************************
2
3 Siano Mobile Silicon, Inc.
4 MDTV receiver kernel modules.
5 Copyright (C) 2006-2008, Uri Shkolnik
6
7 This program is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 2 of the License, or
10 (at your option) any later version.
11
12  This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program.  If not, see <http://www.gnu.org/licenses/>.
19
20 ****************************************************************/
21 //#define PXA_310_LV
22
23 #include <linux/kernel.h>
24 #include <asm/irq.h>
25 //#include <asm/hardware.h>
26
27 #include <linux/init.h>
28 #include <linux/module.h>
29
30 #include <linux/interrupt.h>
31 #include <linux/irq.h>
32 #include <linux/dma-mapping.h>
33 #include <asm/dma.h>
34 #include <linux/module.h>
35 #include <linux/device.h>
36 #include <linux/delay.h>
37 #include <asm/io.h>
38 #include "smsdbg_prn.h"
39 #include <linux/spi/spi.h>
40 #include <mach/gpio.h>
41 #include "smscoreapi.h"
42 #include <linux/notifier.h>
43
44 #include <mach/iomux.h>
45
46 //#define CMMB_1186_SPIIRQ RK2818_PIN_PE1  //This Pin is SDK Board GPIOPortE_Pin1 
47 //#define CMMB_1186_PWR_EN   GPIOPortH_Pin7//This Pin is SDK Board GPIOPortE_Pin1 
48
49
50
51 /*! macro to align the divider to the proper offset in the register bits */
52 #define CLOCK_DIVIDER(i)((i-1)<<8)      /* 1-4096 */
53
54
55 #define SPI_PACKET_SIZE 256
56
57
58 unsigned  long u_irq_count =0;
59
60 static unsigned int dma_rxbuf_phy_addr ;
61 static unsigned int dma_txbuf_phy_addr ;
62
63 static int     rx_dma_channel =0 ;
64 static int     tx_dma_channel =0 ;
65 static volatile int     dma_len = 0 ;
66 static volatile int     tx_len  = 0 ;
67
68 static struct ssp_dev*  panic_sspdev = NULL ;
69
70
71 extern void smscore_panic_print(void);
72 extern void spilog_panic_print(void) ;
73 static void chip_powerdown();
74 extern void smschar_reset_device(void);
75
76 static int sms_panic_handler(struct notifier_block *this,
77                               unsigned long         event,
78                               void                  *unused) 
79 {
80     static int panic_event_handled = 0;
81     if(!panic_event_handled)
82     {
83        smscore_panic_print() ;
84        spilog_panic_print() ; 
85        sms_debug("last tx_len = %d\n",tx_len) ;
86        sms_debug("last DMA len = %d\n",dma_len) ;
87
88        panic_event_handled =1 ; 
89     }
90     return NOTIFY_OK ;
91 }
92
93 static struct notifier_block sms_panic_notifier = {
94         .notifier_call  = sms_panic_handler,
95         .next           = NULL,
96         .priority       = 150   /* priority: INT_MAX >= x >= 0 */
97 };
98
99
100
101
102 /*!  GPIO functions for PXA3xx
103 */
104 // obsolete
105 void pxa3xx_gpio_set_rising_edge_detect (int gpio_id, int dir)
106 {
107 #if 0
108         ;
109 #endif
110 }
111
112 void pxa3xx_gpio_set_direction(int gpio_id , int dir)
113 {
114 #if 0
115         ;
116 #endif
117 }
118 //////////////////////////////////////////////////////////
119
120 /* physical layer variables */
121 /*! global bus data */
122 struct spiphy_dev_s {
123         //struct ssp_dev sspdev;        /*!< ssp port configuration */
124         struct completion transfer_in_process;
125     struct spi_device *Smsdevice; 
126         void (*interruptHandler) (void *);
127         void *intr_context;
128         struct device *dev;     /*!< device model stuff */
129         int rx_dma_channel;
130         int tx_dma_channel;
131         int rx_buf_len;
132         int tx_buf_len;
133 };
134
135
136
137
138 /*!
139 invert the endianness of a single 32it integer
140
141 \param[in]              u: word to invert
142
143 \return         the inverted word
144 */
145 static inline u32 invert_bo(u32 u)
146 {
147         return ((u & 0xff) << 24) | ((u & 0xff00) << 8) | ((u & 0xff0000) >> 8)
148                 | ((u & 0xff000000) >> 24);
149 }
150
151 /*!
152 invert the endianness of a data buffer
153
154 \param[in]              buf: buffer to invert
155 \param[in]              len: buffer length
156
157 \return         the inverted word
158 */
159
160 static int invert_endianness(char *buf, int len)
161 {
162         int i;
163         u32 *ptr = (u32 *) buf;
164
165         len = (len + 3) / 4;
166         for (i = 0; i < len; i++, ptr++)
167                 *ptr = invert_bo(*ptr);
168
169         return 4 * ((len + 3) & (~3));
170 }
171
172 /*! Map DMA buffers when request starts
173
174 \return error status
175 */
176 static unsigned long dma_map_buf(struct spiphy_dev_s *spiphy_dev, char *buf,
177                 int len, int direction)
178 {
179         unsigned long phyaddr;  /* map dma buffers */
180         if (!buf) {
181                 PERROR(" NULL buffers to map\n");
182                 return 0;
183         }
184         /* map buffer */
185 /*
186         phyaddr = dma_map_single(spiphy_dev->dev, buf, len, direction);
187         if (dma_mapping_error(phyaddr)) {
188                 PERROR("exiting  with error\n");
189                 return 0;
190         }
191 */
192         return phyaddr;
193 }
194
195 static irqreturn_t spibus_interrupt(int irq, void *context)
196 {
197         struct spiphy_dev_s *spiphy_dev = (struct spiphy_dev_s *) context;
198     
199         u_irq_count ++;
200     
201 //      PDEBUG("INT counter = %d\n", u_irq_count);
202         printk("cmmb siano 1186 int\n");
203         sms_info("spibus_interrupt %d\n", u_irq_count);
204     
205         if (spiphy_dev->interruptHandler)
206                 spiphy_dev->interruptHandler(spiphy_dev->intr_context);
207     
208         return IRQ_HANDLED;
209
210 }
211
212 /*!     DMA controller callback - called only on BUS error condition
213
214 \param[in]      channel: DMA channel with error
215 \param[in]      data: Unused
216 \param[in]      regs: Unused
217 \return         void
218 */
219
220 //extern dma_addr_t common_buf_end ;
221
222 static void spibus_dma_handler(int channel, void *context)
223 {
224 #if 0
225
226 #endif   
227 }
228
229 void smsspibus_xfer(void *context, unsigned char *txbuf,
230                     unsigned long txbuf_phy_addr, unsigned char *rxbuf,
231                     unsigned long rxbuf_phy_addr, int len)
232 {
233     struct spiphy_dev_s *spiphy_dev = (struct spiphy_dev_s *) context;
234     unsigned char *temp = NULL;
235     int ret;
236
237 #if SIANO_HALFDUPLEX
238         if(txbuf)
239         {
240            //sms_debug("tx_buf:%x,%x,%x,%x,%x,%x", txbuf[0], txbuf[1], txbuf[2], txbuf[3], txbuf[4],txbuf[5]);
241            ret = spi_write(spiphy_dev->Smsdevice, txbuf, len);
242         } else {
243                 if ((rxbuf)&&(len != 16))
244                         ret = spi_read(spiphy_dev->Smsdevice, rxbuf, len);
245         }
246 #else
247     if(txbuf)
248     {
249        //sms_debug("tx_buf:%x,%x,%x,%x,%x,%x", txbuf[0], txbuf[1], txbuf[2], txbuf[3], txbuf[4],txbuf[5]);
250        ret = spi_write(spiphy_dev->Smsdevice, txbuf, len);
251     }
252      
253     if ((rxbuf)&&(len != 16))
254         ret = spi_read(spiphy_dev->Smsdevice, rxbuf, len);
255 #endif
256
257     //sms_debug("rxbuf 4, 5,8,9=%x,%x,%x,%x\n",rxbuf[4],rxbuf[5],rxbuf[8],rxbuf[9]);
258     //printk("len=%x,rxbuf 4, 5,8,9Mlen=%x,%x,%x,%x,%x,%x\n",len,rxbuf[4],rxbuf[5],rxbuf[8],rxbuf[9],rxbuf[13],rxbuf[12]);
259
260 }
261
262 void smschipreset(void *context)
263 {
264
265 }
266
267 static struct ssp_state  sms_ssp_state ;
268
269 void smsspibus_ssp_suspend(void* context )
270 {
271         struct spiphy_dev_s *spiphy_dev ;
272
273         sms_info("entering smsspibus_ssp_suspend\n");
274         
275         if(!context)
276         {
277                 sms_info("smsspibus_ssp_suspend context NULL \n") ;
278                 return ;
279         }
280         spiphy_dev = (struct spiphy_dev_s *) context;
281
282  // free_irq(gpio_to_irq(CMMB_1186_SPIIRQ), NULL);
283
284         chip_powerdown();
285     
286 }
287 static void chip_poweron()
288 {
289 #if 0    
290 #ifdef CONFIG_MACH_LC6830_PHONE_BOARD_1_0
291         gpio_direction_output(mfp_to_gpio(MFP_PIN_GPIO4), 1);
292         mdelay(100);
293         gpio_direction_output(mfp_to_gpio(MFP_PIN_GPIO6), 1);
294         mdelay(1);
295 #elif defined CONFIG_MACH_LC6830_PHONE_BOARD_1_1
296         gpio_direction_output(mfp_to_gpio(MFP_PIN_GPIO6), 1);
297         mdelay(50);
298         gpio_direction_output(mfp_to_gpio(MFP_PIN_GPIO8), 1);
299         mdelay(200);
300         gpio_direction_output(mfp_to_gpio(MFP_PIN_GPIO4), 1);
301         mdelay(1);
302 #endif
303 #else
304
305 #endif
306
307 //1186 cmmb power on
308 //set the SPI CS mode , zyc
309         //rk2818_mux_api_set(GPIOB4_SPI0CS0_MMC0D4_NAME,1);
310
311         gpio_direction_output(CMMB_1186_POWER_RESET,0);
312         gpio_direction_output(CMMB_1186_POWER_DOWN,0);
313
314 //      GPIOSetPinDirection(CMMB_1186_POWER_ENABLE,1);
315         gpio_direction_output(CMMB_1186_POWER_ENABLE,0);
316         mdelay(100);
317         gpio_direction_output(CMMB_1186_POWER_ENABLE,1);
318         mdelay(100);
319
320         gpio_direction_output(CMMB_1186_POWER_DOWN,1);
321         mdelay(100);
322         gpio_direction_output(CMMB_1186_POWER_RESET,1);
323         mdelay(200);
324
325         printk("cmmb chip_poweron !!!!\n");
326 }
327
328 static void chip_powerdown()
329 {
330 #if 0    //hzb test
331 #ifdef CONFIG_MACH_LC6830_PHONE_BOARD_1_0
332         gpio_direction_output(mfp_to_gpio(MFP_PIN_GPIO4), 0);
333         mdelay(50);
334         gpio_direction_output(mfp_to_gpio(MFP_PIN_GPIO6), 0);
335 #elif defined CONFIG_MACH_LC6830_PHONE_BOARD_1_1
336         gpio_direction_output(mfp_to_gpio(MFP_PIN_GPIO4), 0);
337         mdelay(100);
338         gpio_direction_output(mfp_to_gpio(MFP_PIN_GPIO8), 0);
339         mdelay(100);
340         gpio_direction_output(mfp_to_gpio(MFP_PIN_GPIO6), 0);
341         mdelay(1);
342 #endif
343 #else
344
345
346 #endif
347
348 //1186 cmmb power down
349 #if 1
350 //      GPIOSetPinDirection(CMMB_1186_POWER_ENABLE,1);
351         gpio_direction_output(CMMB_1186_POWER_ENABLE,0);
352         mdelay(300);
353 //set the CS0 as gpio mode 
354
355 //      rk2818_mux_api_set(GPIOB4_SPI0CS0_MMC0D4_NAME,0);
356 //      gpio_direction_output(GPIOB4_SPI0CS0_MMC0D4_NAME,0);
357
358         printk("cmmb chip_powerdown !!!!\n");
359
360 #endif
361 //for test
362         //chip_poweron();
363 }
364
365 int smsspibus_ssp_resume(void* context) 
366 {
367     int ret;
368     struct spiphy_dev_s *spiphy_dev ;
369     u32 mode = 0, flags = 0, psp_flags = 0, speed = 0;
370     printk("entering smsspibus_ssp_resume\n");
371
372     if(!context){
373         PERROR("smsspibus_ssp_resume context NULL \n");
374         return -1;
375     }
376     spiphy_dev = (struct spiphy_dev_s *) context;
377     chip_poweron();
378     //free_irq(gpio_to_irq(CMMB_1186_SPIIRQ), spiphy_dev);
379     //printk("siano 1186 request irq\n");
380     //gpio_pull_updown(CMMB_1186_SPIIRQ,GPIOPullDown);
381     //ret = request_gpio_irq(CMMB_1186_SPIIRQ, (pFunc)spibus_interrupt, GPIOEdgelRising, spiphy_dev);       
382     //request_irq(gpio_to_irq(CMMB_1186_SPIIRQ),spibus_interrupt,IRQF_TRIGGER_RISING,NULL,spiphy_dev);
383     if(ret<0){
384         printk("siano1186 request irq failed !!\n");
385         ret = -EBUSY;
386         goto fail1;
387     }
388     return 0 ;
389 fail1:
390           free_irq(gpio_to_irq(CMMB_1186_SPIIRQ), NULL);
391     return -1 ;
392 }
393
394 void *smsspiphy_init(void *context, void (*smsspi_interruptHandler) (void *),
395                      void *intr_context)
396 {
397         int ret;
398         struct spiphy_dev_s *spiphy_dev;
399         u32 mode = 0, flags = 0, psp_flags = 0, speed = 0;
400         int error;
401
402     sms_debug("smsspiphy_init\n");
403     
404         spiphy_dev = kmalloc(sizeof(struct spiphy_dev_s), GFP_KERNEL);
405     if(!spiphy_dev )
406     {
407                 sms_err("spiphy_dev is null in smsspiphy_init\n") ;
408         return NULL;
409         }
410         
411         chip_powerdown();
412         spiphy_dev->interruptHandler = smsspi_interruptHandler;
413         spiphy_dev->intr_context = intr_context;
414   spiphy_dev->Smsdevice = (struct spi_device*)context;
415     
416     //gpio_pull_updown(CMMB_1186_SPIIRQ, IRQT_FALLING);
417     //ÉèÖÃCMMB ÖжϽÅIOMUX      
418     
419         rk2818_mux_api_set(GPIOA6_FLASHCS2_SEL_NAME, 0);
420         error = gpio_request(CMMB_1186_SPIIRQ,"cmmb irq");
421         if (error) {
422                 //dev_err(&pdev->dev, "failed to request play key gpio\n");
423                 //goto free_gpio;
424                 printk("gpio request error\n");
425         }
426     //ret = request_gpio_irq(CMMB_1186_SPIIRQ, spibus_interrupt, GPIOEdgelRising, spiphy_dev);//
427     gpio_pull_updown(CMMB_1186_SPIIRQ,GPIOPullUp);
428     //ret = request_gpio_irq(CMMB_-rwxrwxrwx 1 root root     8 2010-09-20 17:43 built-in.o
429     //-rwxrwxrwx 1 root root  6927 2010-09-19 10:42 compat.h
430     //-rwxrwxrwx 1 root root  1748 2010-09-21 15:06 Kconfig
431     //-rwxrwxrwx 1 root root  2518 2010-09-19 10:42 Makefile
432     //-rwxrwxrwx 1 root root    37 2010-09-21 20:27 modules.order
433     //-rwxrwxrwx 1 root root  9890 2010-09-19 10:42 sms-cards.c
434     //-rwxrwxrwx 1 root root  2752 2010-09-19 10:42 sms-cards.h
435     //-rwxrwxrwx 1 root root  5416 2010-09-21 19:47 sms-cards.o
436     //-rwxrwxrwx 1 root root 20493 2010-09-21 19:46 smschar.c
437     //-rwxrwxrwx 1 root root  1916 2010-09-19 10:42 smscharioctl.h
438     //-rwxrwxrwx 1 root root 12440 2010-09-21 19:47 smschar.o
439     //-rwxrwxrwx 1 root root 53173 2010-09-21 19:46 smscoreapi.c
440     //-rwxrwxrwx 1 root root 16701 2010-09-21 19:46 smscoreapi.h
441     //-rwxrwxrwx 1 root root 25516 2010-09-21 19:47 smscoreapi.o
442     //-rwxrwxrwx 1 root root  1982 2010-09-19 10:42 smsdbg_prn.h
443     //-rwxrwxrwx 1 root root  2409 2010-09-19 10:42 smsendian.c
444     //-rwxrwxrwx 1 root root  1100 2010-09-19 10:42 smsendian.h
445     //-rwxrwxrwx 1 root root  1140 2010-09-21 19:47 smsendian.o
446     //-rwxrwxrwx 1 root root 58990 2010-09-21 19:48 smsmdtv.ko
447     //-rwxrwxrwx 1 root root  1578 2010-09-19 16:15 smsmdtv.mod.c
448     //-rwxrwxrwx 1 root root  2984 2010-09-20 17:43 smsmdtv.mod.o
449     //-rwxrwxrwx 1 root root 56673 2010-09-21 19:47 smsmdtv.o
450     //-rwxrwxrwx 1 root root 11950 2010-09-21 19:46 smsspicommon.c
451     //-rwxrwxrwx 1 root root  2496 2010-09-19 10:42 smsspicommon.h
452     //-rwxrwxrwx 1 root root  3800 2010-09-21 19:47 smsspicommon.o
453     //-rwxrwxrwx 1 root root 23441 2010-09-21 19:46 smsspilog.c
454     //-rwxrwxrwx 1 root root 12260 2010-09-21 19:47 smsspilog.o
455     //-rwxrwxrwx 1 root root  1512 2010-09-19 10:42 smsspiphy.h
456     //-rwxrwxrwx 1 root root 20394 2010-09-17 11:22 smsspiphy_pxa.c
457     //-rwxrwxrwx 1 root root 11895 2010-09-21 19:46 smsspiphy_rk.c
458     //-rwxrwxrwx 1 root root  5480 2010-09-21 19:47 smsspiphy_rk.o
459     //root@zyc-desktop:/usr/android_source/android_cmmb_dev/kernel/kernel/drivers/cmmb/siano# 
460     //
461     //1186_SPIIRQ, (pFunc)spibus_interrupt, GPIOEdgelRising, spiphy_dev);       
462     request_irq(gpio_to_irq(CMMB_1186_SPIIRQ),spibus_interrupt,IRQF_TRIGGER_RISING,"inno_irq",spiphy_dev);
463
464     if(ret<0){
465         printk("siano 1186 request irq failed !!\n");
466         ret = -EBUSY;
467         goto fail1;
468     }
469     
470     atomic_notifier_chain_register(&panic_notifier_list,&sms_panic_notifier);
471     //panic_sspdev =  &(spiphy_dev->sspdev) ;
472         
473         PDEBUG("exiting\n");
474     
475         return spiphy_dev;
476     
477 fail1:
478         free_irq(gpio_to_irq(CMMB_1186_SPIIRQ), spiphy_dev);
479         return 0;
480 }
481
482 int smsspiphy_deinit(void *context)
483 {
484         struct spiphy_dev_s *spiphy_dev = (struct spiphy_dev_s *) context;
485         PDEBUG("entering\n");
486
487         printk("entering smsspiphy_deinit\n");
488
489         panic_sspdev = NULL;
490         atomic_notifier_chain_unregister(&panic_notifier_list,
491                                                  &sms_panic_notifier);
492         chip_powerdown();
493         sms_info("exiting\n");
494         free_irq(gpio_to_irq(CMMB_1186_SPIIRQ), spiphy_dev);
495         gpio_free(CMMB_1186_SPIIRQ);
496         return 0;
497 }
498
499 void smsspiphy_set_config(struct spiphy_dev_s *spiphy_dev, int clock_divider)
500 {
501         ;
502 }
503
504 void prepareForFWDnl(void *context)
505 {
506         struct spiphy_dev_s *spiphy_dev = (struct spiphy_dev_s *) context;
507         smsspiphy_set_config(spiphy_dev, 3);
508         msleep(100);
509 }
510
511 void fwDnlComplete(void *context, int App)
512 {
513         struct spiphy_dev_s *spiphy_dev = (struct spiphy_dev_s *) context;
514         smsspiphy_set_config(spiphy_dev, 1);
515         msleep(100);
516 }