modify smsspiphy_rk.c,set the gpio type as pull up
[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 //#define CMMB_1186_SPIIRQ RK2818_PIN_PE1  //This Pin is SDK Board GPIOPortE_Pin1 
45 //#define CMMB_1186_PWR_EN   GPIOPortH_Pin7//This Pin is SDK Board GPIOPortE_Pin1 
46
47
48
49 /*! macro to align the divider to the proper offset in the register bits */
50 #define CLOCK_DIVIDER(i)((i-1)<<8)      /* 1-4096 */
51
52
53 #define SPI_PACKET_SIZE 256
54
55
56 unsigned  long u_irq_count =0;
57
58 static unsigned int dma_rxbuf_phy_addr ;
59 static unsigned int dma_txbuf_phy_addr ;
60
61 static int     rx_dma_channel =0 ;
62 static int     tx_dma_channel =0 ;
63 static volatile int     dma_len = 0 ;
64 static volatile int     tx_len  = 0 ;
65
66 static struct ssp_dev*  panic_sspdev = NULL ;
67
68
69 extern void smscore_panic_print(void);
70 extern void spilog_panic_print(void) ;
71 static void chip_powerdown();
72 extern void smschar_reset_device(void);
73
74 static int sms_panic_handler(struct notifier_block *this,
75                               unsigned long         event,
76                               void                  *unused) 
77 {
78     static int panic_event_handled = 0;
79     if(!panic_event_handled)
80     {
81        smscore_panic_print() ;
82        spilog_panic_print() ; 
83        sms_debug("last tx_len = %d\n",tx_len) ;
84        sms_debug("last DMA len = %d\n",dma_len) ;
85
86        panic_event_handled =1 ; 
87     }
88     return NOTIFY_OK ;
89 }
90
91 static struct notifier_block sms_panic_notifier = {
92         .notifier_call  = sms_panic_handler,
93         .next           = NULL,
94         .priority       = 150   /* priority: INT_MAX >= x >= 0 */
95 };
96
97
98
99
100 /*!  GPIO functions for PXA3xx
101 */
102 // obsolete
103 void pxa3xx_gpio_set_rising_edge_detect (int gpio_id, int dir)
104 {
105 #if 0
106         ;
107 #endif
108 }
109
110 void pxa3xx_gpio_set_direction(int gpio_id , int dir)
111 {
112 #if 0
113         ;
114 #endif
115 }
116 //////////////////////////////////////////////////////////
117
118 /* physical layer variables */
119 /*! global bus data */
120 struct spiphy_dev_s {
121         //struct ssp_dev sspdev;        /*!< ssp port configuration */
122         struct completion transfer_in_process;
123     struct spi_device *Smsdevice; 
124         void (*interruptHandler) (void *);
125         void *intr_context;
126         struct device *dev;     /*!< device model stuff */
127         int rx_dma_channel;
128         int tx_dma_channel;
129         int rx_buf_len;
130         int tx_buf_len;
131 };
132
133
134
135
136 /*!
137 invert the endianness of a single 32it integer
138
139 \param[in]              u: word to invert
140
141 \return         the inverted word
142 */
143 static inline u32 invert_bo(u32 u)
144 {
145         return ((u & 0xff) << 24) | ((u & 0xff00) << 8) | ((u & 0xff0000) >> 8)
146                 | ((u & 0xff000000) >> 24);
147 }
148
149 /*!
150 invert the endianness of a data buffer
151
152 \param[in]              buf: buffer to invert
153 \param[in]              len: buffer length
154
155 \return         the inverted word
156 */
157
158 static int invert_endianness(char *buf, int len)
159 {
160         int i;
161         u32 *ptr = (u32 *) buf;
162
163         len = (len + 3) / 4;
164         for (i = 0; i < len; i++, ptr++)
165                 *ptr = invert_bo(*ptr);
166
167         return 4 * ((len + 3) & (~3));
168 }
169
170 /*! Map DMA buffers when request starts
171
172 \return error status
173 */
174 static unsigned long dma_map_buf(struct spiphy_dev_s *spiphy_dev, char *buf,
175                 int len, int direction)
176 {
177         unsigned long phyaddr;  /* map dma buffers */
178         if (!buf) {
179                 PERROR(" NULL buffers to map\n");
180                 return 0;
181         }
182         /* map buffer */
183 /*
184         phyaddr = dma_map_single(spiphy_dev->dev, buf, len, direction);
185         if (dma_mapping_error(phyaddr)) {
186                 PERROR("exiting  with error\n");
187                 return 0;
188         }
189 */
190         return phyaddr;
191 }
192
193 static irqreturn_t spibus_interrupt(int irq, void *context)
194 {
195         struct spiphy_dev_s *spiphy_dev = (struct spiphy_dev_s *) context;
196     
197         u_irq_count ++;
198     
199 //      PDEBUG("INT counter = %d\n", u_irq_count);
200         printk("cmmb siano 1186 int\n");
201         sms_info("spibus_interrupt %d\n", u_irq_count);
202     
203         if (spiphy_dev->interruptHandler)
204                 spiphy_dev->interruptHandler(spiphy_dev->intr_context);
205     
206         return IRQ_HANDLED;
207
208 }
209
210 /*!     DMA controller callback - called only on BUS error condition
211
212 \param[in]      channel: DMA channel with error
213 \param[in]      data: Unused
214 \param[in]      regs: Unused
215 \return         void
216 */
217
218 //extern dma_addr_t common_buf_end ;
219
220 static void spibus_dma_handler(int channel, void *context)
221 {
222 #if 0
223
224 #endif   
225 }
226
227 void smsspibus_xfer(void *context, unsigned char *txbuf,
228                     unsigned long txbuf_phy_addr, unsigned char *rxbuf,
229                     unsigned long rxbuf_phy_addr, int len)
230 {
231     struct spiphy_dev_s *spiphy_dev = (struct spiphy_dev_s *) context;
232     unsigned char *temp = NULL;
233     int ret;
234
235 #if SIANO_HALFDUPLEX
236         if(txbuf)
237         {
238            //sms_debug("tx_buf:%x,%x,%x,%x,%x,%x", txbuf[0], txbuf[1], txbuf[2], txbuf[3], txbuf[4],txbuf[5]);
239            ret = spi_write(spiphy_dev->Smsdevice, txbuf, len);
240         } else {
241                 if ((rxbuf)&&(len != 16))
242                         ret = spi_read(spiphy_dev->Smsdevice, rxbuf, len);
243         }
244 #else
245     if(txbuf)
246     {
247        //sms_debug("tx_buf:%x,%x,%x,%x,%x,%x", txbuf[0], txbuf[1], txbuf[2], txbuf[3], txbuf[4],txbuf[5]);
248        ret = spi_write(spiphy_dev->Smsdevice, txbuf, len);
249     }
250      
251     if ((rxbuf)&&(len != 16))
252         ret = spi_read(spiphy_dev->Smsdevice, rxbuf, len);
253 #endif
254
255     //sms_debug("rxbuf 4, 5,8,9=%x,%x,%x,%x\n",rxbuf[4],rxbuf[5],rxbuf[8],rxbuf[9]);
256     //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]);
257
258 }
259
260 void smschipreset(void *context)
261 {
262
263 }
264
265 static struct ssp_state  sms_ssp_state ;
266
267 void smsspibus_ssp_suspend(void* context )
268 {
269         struct spiphy_dev_s *spiphy_dev ;
270
271         sms_info("entering smsspibus_ssp_suspend\n");
272         
273         if(!context)
274         {
275                 sms_info("smsspibus_ssp_suspend context NULL \n") ;
276                 return ;
277         }
278         spiphy_dev = (struct spiphy_dev_s *) context;
279
280   free_irq(gpio_to_irq(CMMB_1186_SPIIRQ), NULL);
281
282         chip_powerdown();
283     
284 }
285 static void chip_poweron()
286 {
287 #if 0    
288 #ifdef CONFIG_MACH_LC6830_PHONE_BOARD_1_0
289         gpio_direction_output(mfp_to_gpio(MFP_PIN_GPIO4), 1);
290         mdelay(100);
291         gpio_direction_output(mfp_to_gpio(MFP_PIN_GPIO6), 1);
292         mdelay(1);
293 #elif defined CONFIG_MACH_LC6830_PHONE_BOARD_1_1
294         gpio_direction_output(mfp_to_gpio(MFP_PIN_GPIO6), 1);
295         mdelay(50);
296         gpio_direction_output(mfp_to_gpio(MFP_PIN_GPIO8), 1);
297         mdelay(200);
298         gpio_direction_output(mfp_to_gpio(MFP_PIN_GPIO4), 1);
299         mdelay(1);
300 #endif
301 #else
302
303 #endif
304
305 //1186 cmmb power on
306 //set the SPI CS mode , zyc
307         //rk2818_mux_api_set(GPIOB4_SPI0CS0_MMC0D4_NAME,1);
308
309         gpio_direction_output(CMMB_1186_POWER_RESET,0);
310         gpio_direction_output(CMMB_1186_POWER_DOWN,0);
311
312 //      GPIOSetPinDirection(CMMB_1186_POWER_ENABLE,1);
313         gpio_direction_output(CMMB_1186_POWER_ENABLE,0);
314         mdelay(100);
315         gpio_direction_output(CMMB_1186_POWER_ENABLE,1);
316         mdelay(100);
317
318         gpio_direction_output(CMMB_1186_POWER_DOWN,1);
319         mdelay(100);
320         gpio_direction_output(CMMB_1186_POWER_RESET,1);
321         mdelay(200);
322
323         printk("cmmb chip_poweron !!!!\n");
324 }
325
326 static void chip_powerdown()
327 {
328 #if 0    //hzb test
329 #ifdef CONFIG_MACH_LC6830_PHONE_BOARD_1_0
330         gpio_direction_output(mfp_to_gpio(MFP_PIN_GPIO4), 0);
331         mdelay(50);
332         gpio_direction_output(mfp_to_gpio(MFP_PIN_GPIO6), 0);
333 #elif defined CONFIG_MACH_LC6830_PHONE_BOARD_1_1
334         gpio_direction_output(mfp_to_gpio(MFP_PIN_GPIO4), 0);
335         mdelay(100);
336         gpio_direction_output(mfp_to_gpio(MFP_PIN_GPIO8), 0);
337         mdelay(100);
338         gpio_direction_output(mfp_to_gpio(MFP_PIN_GPIO6), 0);
339         mdelay(1);
340 #endif
341 #else
342
343
344 #endif
345
346 //1186 cmmb power down
347 #if 1
348 //      GPIOSetPinDirection(CMMB_1186_POWER_ENABLE,1);
349         gpio_direction_output(CMMB_1186_POWER_ENABLE,0);
350         mdelay(300);
351 //set the CS0 as gpio mode 
352
353 //      rk2818_mux_api_set(GPIOB4_SPI0CS0_MMC0D4_NAME,0);
354 //      gpio_direction_output(GPIOB4_SPI0CS0_MMC0D4_NAME,0);
355
356         printk("cmmb chip_powerdown !!!!\n");
357
358 #endif
359 //for test
360         //chip_poweron();
361 }
362
363 int smsspibus_ssp_resume(void* context) 
364 {
365     int ret;
366     struct spiphy_dev_s *spiphy_dev ;
367     u32 mode = 0, flags = 0, psp_flags = 0, speed = 0;
368     printk("entering smsspibus_ssp_resume\n");
369
370     if(!context){
371         PERROR("smsspibus_ssp_resume context NULL \n");
372         return -1;
373     }
374     spiphy_dev = (struct spiphy_dev_s *) context;
375     chip_poweron();
376     //free_irq(gpio_to_irq(CMMB_1186_SPIIRQ), spiphy_dev);
377     //printk("siano 1186 request irq\n");
378     //gpio_pull_updown(CMMB_1186_SPIIRQ,GPIOPullDown);
379     //ret = request_gpio_irq(CMMB_1186_SPIIRQ, (pFunc)spibus_interrupt, GPIOEdgelRising, spiphy_dev);       
380     //request_irq(gpio_to_irq(CMMB_1186_SPIIRQ),spibus_interrupt,IRQF_TRIGGER_RISING,NULL,spiphy_dev);
381     if(ret<0){
382         printk("siano1186 request irq failed !!\n");
383         ret = -EBUSY;
384         goto fail1;
385     }
386     return 0 ;
387 fail1:
388           free_irq(gpio_to_irq(CMMB_1186_SPIIRQ), NULL);
389     return -1 ;
390 }
391
392
393 void *smsspiphy_init(void *context, void (*smsspi_interruptHandler) (void *),
394                      void *intr_context)
395 {
396         int ret;
397         struct spiphy_dev_s *spiphy_dev;
398         u32 mode = 0, flags = 0, psp_flags = 0, speed = 0;
399         int error;
400
401     sms_debug("smsspiphy_init\n");
402     
403         spiphy_dev = kmalloc(sizeof(struct spiphy_dev_s), GFP_KERNEL);
404     if(!spiphy_dev )
405     {
406                 sms_err("spiphy_dev is null in smsspiphy_init\n") ;
407         return NULL;
408         }
409         chip_powerdown();
410         spiphy_dev->interruptHandler = smsspi_interruptHandler;
411         spiphy_dev->intr_context = intr_context;
412   spiphy_dev->Smsdevice = (struct spi_device*)context;
413     
414     //gpio_pull_updown(CMMB_1186_SPIIRQ, IRQT_FALLING);
415         error = gpio_request(CMMB_1186_SPIIRQ,"cmmb irq");
416         if (error) {
417                 //dev_err(&pdev->dev, "failed to request play key gpio\n");
418                 //goto free_gpio;
419                 printk("gpio request error\n");
420         }
421     //ret = request_gpio_irq(CMMB_1186_SPIIRQ, spibus_interrupt, GPIOEdgelRising, spiphy_dev);//
422     gpio_pull_updown(CMMB_1186_SPIIRQ,GPIOPullUp);
423     //ret = request_gpio_irq(CMMB_1186_SPIIRQ, (pFunc)spibus_interrupt, GPIOEdgelRising, spiphy_dev);       
424     request_irq(gpio_to_irq(CMMB_1186_SPIIRQ),spibus_interrupt,IRQF_TRIGGER_RISING,NULL,spiphy_dev);
425
426     if(ret<0){
427         printk("siano 1186 request irq failed !!\n");
428         ret = -EBUSY;
429         goto fail1;
430     }
431     
432     atomic_notifier_chain_register(&panic_notifier_list,&sms_panic_notifier);
433     //panic_sspdev =  &(spiphy_dev->sspdev) ;
434         
435         PDEBUG("exiting\n");
436     
437         return spiphy_dev;
438     
439 fail1:
440         free_irq(gpio_to_irq(CMMB_1186_SPIIRQ), NULL);
441         return 0;
442 }
443
444 int smsspiphy_deinit(void *context)
445 {
446         struct spiphy_dev_s *spiphy_dev = (struct spiphy_dev_s *) context;
447         PDEBUG("entering\n");
448
449         printk("entering smsspiphy_deinit\n");
450
451         panic_sspdev = NULL;
452         atomic_notifier_chain_unregister(&panic_notifier_list,
453                                                  &sms_panic_notifier);
454         chip_powerdown();
455         sms_info("exiting\n");
456         free_irq(gpio_to_irq(CMMB_1186_SPIIRQ), NULL);
457         
458         return 0;
459 }
460
461 void smsspiphy_set_config(struct spiphy_dev_s *spiphy_dev, int clock_divider)
462 {
463         ;
464 }
465
466 void prepareForFWDnl(void *context)
467 {
468         struct spiphy_dev_s *spiphy_dev = (struct spiphy_dev_s *) context;
469         smsspiphy_set_config(spiphy_dev, 3);
470         msleep(100);
471 }
472
473 void fwDnlComplete(void *context, int App)
474 {
475         struct spiphy_dev_s *spiphy_dev = (struct spiphy_dev_s *) context;
476         smsspiphy_set_config(spiphy_dev, 1);
477         msleep(100);
478 }