1 /****************************************************************
3 Siano Mobile Silicon, Inc.
4 MDTV receiver kernel modules.
5 Copyright (C) 2006-2008, Uri Shkolnik
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.
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.
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/>.
20 ****************************************************************/
23 #include <linux/kernel.h>
25 //#include <asm/hardware.h>
27 #include <linux/init.h>
28 #include <linux/module.h>
30 #include <linux/interrupt.h>
31 #include <linux/irq.h>
32 #include <linux/dma-mapping.h>
34 #include <linux/module.h>
35 #include <linux/device.h>
36 #include <linux/delay.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>
44 #include <mach/iomux.h>
45 #include "smsspiphy.h"
46 //#include <mach/cmmb_io.h>
47 //#define CMMB_1186_SPIIRQ RK2818_PIN_PE1 //This Pin is SDK Board GPIOPortE_Pin1
48 //#define CMMB_1186_PWR_EN GPIOPortH_Pin7//This Pin is SDK Board GPIOPortE_Pin1
51 //define the gpio used
52 #define CMMB_1186_SPIIRQ RK2818_PIN_PA6 //This Pin is SDK Board GPIOPortA_Pin6
53 #define CMMB_1186_POWER_DOWN FPGA_PIO2_09
54 #define CMMB_1186_POWER_ENABLE FPGA_PIO4_03
55 #define CMMB_1186_POWER_RESET FPGA_PIO2_06
58 /*! macro to align the divider to the proper offset in the register bits */
59 #define CLOCK_DIVIDER(i)((i-1)<<8) /* 1-4096 */
62 #define SPI_PACKET_SIZE 256
65 unsigned long u_irq_count =0;
67 static unsigned int dma_rxbuf_phy_addr ;
68 static unsigned int dma_txbuf_phy_addr ;
70 static int rx_dma_channel =0 ;
71 static int tx_dma_channel =0 ;
72 static volatile int dma_len = 0 ;
73 static volatile int tx_len = 0 ;
75 static struct ssp_dev* panic_sspdev = NULL ;
76 static struct cmmb_io_def_s* cmmb_io_ctrl =NULL;
78 extern void smscore_panic_print(void);
79 extern void spilog_panic_print(void) ;
80 static void chip_powerdown();
81 extern void smschar_reset_device(void);
83 static int sms_panic_handler(struct notifier_block *this,
87 static int panic_event_handled = 0;
88 if(!panic_event_handled)
90 smscore_panic_print() ;
91 spilog_panic_print() ;
92 sms_debug("last tx_len = %d\n",tx_len) ;
93 sms_debug("last DMA len = %d\n",dma_len) ;
95 panic_event_handled =1 ;
100 static struct notifier_block sms_panic_notifier = {
101 .notifier_call = sms_panic_handler,
103 .priority = 150 /* priority: INT_MAX >= x >= 0 */
109 /*! GPIO functions for PXA3xx
112 void pxa3xx_gpio_set_rising_edge_detect (int gpio_id, int dir)
119 void pxa3xx_gpio_set_direction(int gpio_id , int dir)
125 //////////////////////////////////////////////////////////
127 /* physical layer variables */
128 /*! global bus data */
129 struct spiphy_dev_s {
130 //struct ssp_dev sspdev; /*!< ssp port configuration */
131 struct completion transfer_in_process;
132 struct spi_device *Smsdevice;
133 void (*interruptHandler) (void *);
135 struct device *dev; /*!< device model stuff */
146 invert the endianness of a single 32it integer
148 \param[in] u: word to invert
150 \return the inverted word
152 static inline u32 invert_bo(u32 u)
154 return ((u & 0xff) << 24) | ((u & 0xff00) << 8) | ((u & 0xff0000) >> 8)
155 | ((u & 0xff000000) >> 24);
159 invert the endianness of a data buffer
161 \param[in] buf: buffer to invert
162 \param[in] len: buffer length
164 \return the inverted word
167 static int invert_endianness(char *buf, int len)
170 u32 *ptr = (u32 *) buf;
173 for (i = 0; i < len; i++, ptr++)
174 *ptr = invert_bo(*ptr);
176 return 4 * ((len + 3) & (~3));
179 /*! Map DMA buffers when request starts
183 static unsigned long dma_map_buf(struct spiphy_dev_s *spiphy_dev, char *buf,
184 int len, int direction)
186 unsigned long phyaddr; /* map dma buffers */
188 PERROR(" NULL buffers to map\n");
193 phyaddr = dma_map_single(spiphy_dev->dev, buf, len, direction);
194 if (dma_mapping_error(phyaddr)) {
195 PERROR("exiting with error\n");
202 static irqreturn_t spibus_interrupt(int irq, void *context)
204 struct spiphy_dev_s *spiphy_dev = (struct spiphy_dev_s *) context;
208 // PDEBUG("INT counter = %d\n", u_irq_count);
209 // printk("cmmb siano 1186 int\n");
210 sms_info("spibus_interrupt %d\n", u_irq_count);
212 if (spiphy_dev->interruptHandler)
213 spiphy_dev->interruptHandler(spiphy_dev->intr_context);
219 /*! DMA controller callback - called only on BUS error condition
221 \param[in] channel: DMA channel with error
222 \param[in] data: Unused
223 \param[in] regs: Unused
227 //extern dma_addr_t common_buf_end ;
229 static void spibus_dma_handler(int channel, void *context)
236 void smsspibus_xfer(void *context, unsigned char *txbuf,
237 unsigned long txbuf_phy_addr, unsigned char *rxbuf,
238 unsigned long rxbuf_phy_addr, int len)
240 struct spiphy_dev_s *spiphy_dev = (struct spiphy_dev_s *) context;
241 unsigned char *temp = NULL;
247 // sms_debug("tx_buf:%x,%x,%x,%x,%x,%x", txbuf[0], txbuf[1], txbuf[2], txbuf[3], txbuf[4],txbuf[5]);
248 sms_debug("rxbuf 4, 5,6,7,8, 9,10,11=%x,%x,%x,%x",rxbuf[4],rxbuf[5],rxbuf[6],rxbuf[7]);
249 sms_debug(",%x,%x,%x,%x\n",rxbuf[8],rxbuf[9],rxbuf[10],rxbuf[11]);
250 ret = spi_write(spiphy_dev->Smsdevice, txbuf, len);
252 if ((rxbuf)&&(len != 16))
253 ret = spi_read(spiphy_dev->Smsdevice, rxbuf, len);
258 //sms_debug("tx_buf:%x,%x,%x,%x,%x,%x", txbuf[0], txbuf[1], txbuf[2], txbuf[3], txbuf[4],txbuf[5]);
259 ret = spi_write(spiphy_dev->Smsdevice, txbuf, len);
262 if ((rxbuf)&&(len != 16))
263 ret = spi_read(spiphy_dev->Smsdevice, rxbuf, len);
266 //sms_debug("rxbuf 4, 5,6,7,8, 9,10,11=%x,%x,%x,%x",rxbuf[4],rxbuf[5],rxbuf[6],rxbuf[7]);
267 // sms_debug(",%x,%x,%x,%x\n",rxbuf[8],rxbuf[9],rxbuf[10],rxbuf[11]);
268 //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]);
272 void smschipreset(void *context)
277 static struct ssp_state sms_ssp_state ;
279 void smsspibus_ssp_suspend(void* context )
281 struct spiphy_dev_s *spiphy_dev ;
283 sms_info("entering smsspibus_ssp_suspend\n");
287 sms_info("smsspibus_ssp_suspend context NULL \n") ;
290 spiphy_dev = (struct spiphy_dev_s *) context;
292 // free_irq(gpio_to_irq(CMMB_1186_SPIIRQ), NULL);
297 static void chip_poweron()
300 #ifdef CONFIG_MACH_LC6830_PHONE_BOARD_1_0
301 gpio_direction_output(mfp_to_gpio(MFP_PIN_GPIO4), 1);
303 gpio_direction_output(mfp_to_gpio(MFP_PIN_GPIO6), 1);
305 #elif defined CONFIG_MACH_LC6830_PHONE_BOARD_1_1
306 gpio_direction_output(mfp_to_gpio(MFP_PIN_GPIO6), 1);
308 gpio_direction_output(mfp_to_gpio(MFP_PIN_GPIO8), 1);
310 gpio_direction_output(mfp_to_gpio(MFP_PIN_GPIO4), 1);
318 //set the SPI CS mode , zyc
319 //rk2818_mux_api_set(GPIOB4_SPI0CS0_MMC0D4_NAME,1);
323 gpio_direction_output(cmmb_io_ctrl->cmmb_pw_rst,0);
324 gpio_direction_output(cmmb_io_ctrl->cmmb_pw_dwn,0);
326 // GPIOSetPinDirection(CMMB_1186_POWER_ENABLE,1);
328 gpio_direction_output(cmmb_io_ctrl->cmmb_pw_en,1);
329 // gpio_set_value(CMMB_1186_POWER_ENABLE,GPIO_HIGH);
331 // gpio_set_value(CMMB_1186_POWER_DOWN,GPIO_HIGH);
332 gpio_direction_output(cmmb_io_ctrl->cmmb_pw_dwn,1);
335 // gpio_set_value(CMMB_1186_POWER_RESET,GPIO_HIGH);
336 gpio_direction_output(cmmb_io_ctrl->cmmb_pw_rst,1);
340 printk("cmmb chip_poweron !!!!\n");
344 static void chip_powerdown()
347 #ifdef CONFIG_MACH_LC6830_PHONE_BOARD_1_0
348 gpio_direction_output(mfp_to_gpio(MFP_PIN_GPIO4), 0);
350 gpio_direction_output(mfp_to_gpio(MFP_PIN_GPIO6), 0);
351 #elif defined CONFIG_MACH_LC6830_PHONE_BOARD_1_1
352 gpio_direction_output(mfp_to_gpio(MFP_PIN_GPIO4), 0);
354 gpio_direction_output(mfp_to_gpio(MFP_PIN_GPIO8), 0);
356 gpio_direction_output(mfp_to_gpio(MFP_PIN_GPIO6), 0);
364 //1186 cmmb power down
366 // GPIOSetPinDirection(CMMB_1186_POWER_ENABLE,1);
369 gpio_direction_output(cmmb_io_ctrl->cmmb_pw_rst,0);
372 gpio_direction_output(cmmb_io_ctrl->cmmb_pw_dwn,0);
374 gpio_direction_output(cmmb_io_ctrl->cmmb_pw_en,0);
375 // gpio_set_value(CMMB_1186_POWER_RESET,GPIO_LOW);
376 // gpio_set_value(CMMB_1186_POWER_DOWN,GPIO_LOW);
377 // gpio_set_value(CMMB_1186_POWER_ENABLE,GPIO_LOW);
379 //set the CS0 as gpio mode
381 // rk2818_mux_api_set(GPIOB4_SPI0CS0_MMC0D4_NAME,0);
382 // gpio_direction_output(GPIOB4_SPI0CS0_MMC0D4_NAME,0);
384 printk("cmmb chip_powerdown !!!!\n");
392 int smsspibus_ssp_resume(void* context)
395 struct spiphy_dev_s *spiphy_dev ;
396 u32 mode = 0, flags = 0, psp_flags = 0, speed = 0;
397 printk("entering smsspibus_ssp_resume\n");
400 PERROR("smsspibus_ssp_resume context NULL \n");
403 spiphy_dev = (struct spiphy_dev_s *) context;
405 //free_irq(gpio_to_irq(CMMB_1186_SPIIRQ), spiphy_dev);
406 //printk("siano 1186 request irq\n");
407 //gpio_pull_updown(CMMB_1186_SPIIRQ,GPIOPullDown);
408 //ret = request_gpio_irq(CMMB_1186_SPIIRQ, (pFunc)spibus_interrupt, GPIOEdgelRising, spiphy_dev);
409 //request_irq(gpio_to_irq(CMMB_1186_SPIIRQ),spibus_interrupt,IRQF_TRIGGER_RISING,NULL,spiphy_dev);
411 printk("siano1186 request irq failed !!\n");
417 free_irq(gpio_to_irq(cmmb_io_ctrl->cmmb_irq), NULL);
422 static void request_cmmb_gpio()
426 ret = gpio_request(CMMB_1186_POWER_RESET, NULL);
428 printk("%s:failed to request CMMB_1186_POWER_RESET\n",__FUNCTION__);
432 ret = gpio_request(CMMB_1186_POWER_DOWN, NULL);
434 printk("%s:failed to request CMMB_1186_POWER_DOWN\n",__FUNCTION__);
439 ret = gpio_request(CMMB_1186_POWER_ENABLE, NULL);
441 printk("%s:failed to request CMMB_1186_POWER_ENABLE\n",__FUNCTION__);
445 rk2818_mux_api_set(GPIOA6_FLASHCS2_SEL_NAME, 0);
446 ret = gpio_request(CMMB_1186_SPIIRQ,"cmmb irq");
448 //dev_err(&pdev->dev, "failed to request play key gpio\n");
450 printk("gpio request error\n");
453 //ret = request_gpio_irq(CMMB_1186_SPIIRQ, spibus_interrupt, GPIOEdgelRising, spiphy_dev);//
454 gpio_pull_updown(CMMB_1186_SPIIRQ,GPIOPullUp);
455 printk("leave the request_cmmb_gpio\n");
462 if(cmmb_io_ctrl->io_init_mux)
463 cmmb_io_ctrl->io_init_mux();
465 printk("cmmb_io_ctrl->io_init_mux is null !!!!!!!\n");
466 ret = gpio_request(cmmb_io_ctrl->cmmb_pw_rst, NULL);
468 printk("%s:failed to request CMMB_1186_POWER_RESET\n",__FUNCTION__);
472 ret = gpio_request(cmmb_io_ctrl->cmmb_pw_dwn, NULL);
474 printk("%s:failed to request CMMB_1186_POWER_DOWN\n",__FUNCTION__);
479 ret = gpio_request(cmmb_io_ctrl->cmmb_pw_en, NULL);
481 printk("%s:failed to request CMMB_1186_POWER_ENABLE\n",__FUNCTION__);
485 // rk2818_mux_api_set(GPIOA6_FLASHCS2_SEL_NAME, 0);
486 ret = gpio_request(cmmb_io_ctrl->cmmb_irq,"cmmb irq");
488 //dev_err(&pdev->dev, "failed to request play key gpio\n");
490 printk("gpio request error\n");
493 //ret = request_gpio_irq(CMMB_1186_SPIIRQ, spibus_interrupt, GPIOEdgelRising, spiphy_dev);//
494 gpio_pull_updown(cmmb_io_ctrl->cmmb_irq,GPIOPullUp);
495 printk("leave the request_cmmb_gpio\n");
500 static void release_cmmb_gpio()
505 gpio_free(cmmb_io_ctrl->cmmb_pw_rst);
506 gpio_free(cmmb_io_ctrl->cmmb_pw_dwn);
507 gpio_free(cmmb_io_ctrl->cmmb_pw_en);
508 gpio_free(cmmb_io_ctrl->cmmb_irq);
510 printk("leave the release_cmmb_gpio\n");
516 void *smsspiphy_init(void *context, void (*smsspi_interruptHandler) (void *),
520 struct spiphy_dev_s *spiphy_dev;
521 u32 mode = 0, flags = 0, psp_flags = 0, speed = 0;
523 cmmb_io_ctrl = ((struct spi_device*)context)->dev.platform_data;
525 sms_debug("smsspiphy_init\n");
527 spiphy_dev = kmalloc(sizeof(struct spiphy_dev_s), GFP_KERNEL);
530 sms_err("spiphy_dev is null in smsspiphy_init\n") ;
537 spiphy_dev->interruptHandler = smsspi_interruptHandler;
538 spiphy_dev->intr_context = intr_context;
539 spiphy_dev->Smsdevice = (struct spi_device*)context;
541 //gpio_pull_updown(CMMB_1186_SPIIRQ, IRQT_FALLING);
542 //ÉèÖÃCMMB ÖжϽÅIOMUX
543 //ÉêÇëGPIO·Åµ½ request_cmmb_gpio
545 rk2818_mux_api_set(GPIOA6_FLASHCS2_SEL_NAME, 0);
546 error = gpio_request(CMMB_1186_SPIIRQ,"cmmb irq");
548 //dev_err(&pdev->dev, "failed to request play key gpio\n");
550 printk("gpio request error\n");
553 //ret = request_gpio_irq(CMMB_1186_SPIIRQ, spibus_interrupt, GPIOEdgelRising, spiphy_dev);//
554 gpio_pull_updown(CMMB_1186_SPIIRQ,GPIOPullUp);
557 //ret = request_gpio_irq(CMMB_-rwxrwxrwx 1 root root 8 2010-09-20 17:43 built-in.o
558 //-rwxrwxrwx 1 root root 6927 2010-09-19 10:42 compat.h
559 //-rwxrwxrwx 1 root root 1748 2010-09-21 15:06 Kconfig
560 //-rwxrwxrwx 1 root root 2518 2010-09-19 10:42 Makefile
561 //-rwxrwxrwx 1 root root 37 2010-09-21 20:27 modules.order
562 //-rwxrwxrwx 1 root root 9890 2010-09-19 10:42 sms-cards.c
563 //-rwxrwxrwx 1 root root 2752 2010-09-19 10:42 sms-cards.h
564 //-rwxrwxrwx 1 root root 5416 2010-09-21 19:47 sms-cards.o
565 //-rwxrwxrwx 1 root root 20493 2010-09-21 19:46 smschar.c
566 //-rwxrwxrwx 1 root root 1916 2010-09-19 10:42 smscharioctl.h
567 //-rwxrwxrwx 1 root root 12440 2010-09-21 19:47 smschar.o
568 //-rwxrwxrwx 1 root root 53173 2010-09-21 19:46 smscoreapi.c
569 //-rwxrwxrwx 1 root root 16701 2010-09-21 19:46 smscoreapi.h
570 //-rwxrwxrwx 1 root root 25516 2010-09-21 19:47 smscoreapi.o
571 //-rwxrwxrwx 1 root root 1982 2010-09-19 10:42 smsdbg_prn.h
572 //-rwxrwxrwx 1 root root 2409 2010-09-19 10:42 smsendian.c
573 //-rwxrwxrwx 1 root root 1100 2010-09-19 10:42 smsendian.h
574 //-rwxrwxrwx 1 root root 1140 2010-09-21 19:47 smsendian.o
575 //-rwxrwxrwx 1 root root 58990 2010-09-21 19:48 smsmdtv.ko
576 //-rwxrwxrwx 1 root root 1578 2010-09-19 16:15 smsmdtv.mod.c
577 //-rwxrwxrwx 1 root root 2984 2010-09-20 17:43 smsmdtv.mod.o
578 //-rwxrwxrwx 1 root root 56673 2010-09-21 19:47 smsmdtv.o
579 //-rwxrwxrwx 1 root root 11950 2010-09-21 19:46 smsspicommon.c
580 //-rwxrwxrwx 1 root root 2496 2010-09-19 10:42 smsspicommon.h
581 //-rwxrwxrwx 1 root root 3800 2010-09-21 19:47 smsspicommon.o
582 //-rwxrwxrwx 1 root root 23441 2010-09-21 19:46 smsspilog.c
583 //-rwxrwxrwx 1 root root 12260 2010-09-21 19:47 smsspilog.o
584 //-rwxrwxrwx 1 root root 1512 2010-09-19 10:42 smsspiphy.h
585 //-rwxrwxrwx 1 root root 20394 2010-09-17 11:22 smsspiphy_pxa.c
586 //-rwxrwxrwx 1 root root 11895 2010-09-21 19:46 smsspiphy_rk.c
587 //-rwxrwxrwx 1 root root 5480 2010-09-21 19:47 smsspiphy_rk.o
588 //root@zyc-desktop:/usr/android_source/android_cmmb_dev/kernel/kernel/drivers/cmmb/siano#
590 //1186_SPIIRQ, (pFunc)spibus_interrupt, GPIOEdgelRising, spiphy_dev);
592 request_irq(gpio_to_irq(cmmb_io_ctrl->cmmb_irq),spibus_interrupt,IRQF_TRIGGER_RISING,"inno_irq",spiphy_dev);
596 printk("siano 1186 request irq failed !!\n");
601 atomic_notifier_chain_register(&panic_notifier_list,&sms_panic_notifier);
602 //panic_sspdev = &(spiphy_dev->sspdev) ;
609 free_irq(gpio_to_irq(cmmb_io_ctrl->cmmb_irq), spiphy_dev);
613 int smsspiphy_deinit(void *context)
615 struct spiphy_dev_s *spiphy_dev = (struct spiphy_dev_s *) context;
616 PDEBUG("entering\n");
618 printk("entering smsspiphy_deinit\n");
621 atomic_notifier_chain_unregister(&panic_notifier_list,
622 &sms_panic_notifier);
624 sms_info("exiting\n");
625 free_irq(gpio_to_irq(cmmb_io_ctrl->cmmb_irq), spiphy_dev);
626 // gpio_free(CMMB_1186_SPIIRQ);
632 void smsspiphy_set_config(struct spiphy_dev_s *spiphy_dev, int clock_divider)
637 void prepareForFWDnl(void *context)
639 struct spiphy_dev_s *spiphy_dev = (struct spiphy_dev_s *) context;
640 smsspiphy_set_config(spiphy_dev, 3);
644 void fwDnlComplete(void *context, int App)
646 struct spiphy_dev_s *spiphy_dev = (struct spiphy_dev_s *) context;
647 smsspiphy_set_config(spiphy_dev, 1);