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>
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
51 /*! macro to align the divider to the proper offset in the register bits */
52 #define CLOCK_DIVIDER(i)((i-1)<<8) /* 1-4096 */
55 #define SPI_PACKET_SIZE 256
58 unsigned long u_irq_count =0;
60 static unsigned int dma_rxbuf_phy_addr ;
61 static unsigned int dma_txbuf_phy_addr ;
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 ;
68 static struct ssp_dev* panic_sspdev = NULL ;
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);
76 static int sms_panic_handler(struct notifier_block *this,
80 static int panic_event_handled = 0;
81 if(!panic_event_handled)
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) ;
88 panic_event_handled =1 ;
93 static struct notifier_block sms_panic_notifier = {
94 .notifier_call = sms_panic_handler,
96 .priority = 150 /* priority: INT_MAX >= x >= 0 */
102 /*! GPIO functions for PXA3xx
105 void pxa3xx_gpio_set_rising_edge_detect (int gpio_id, int dir)
112 void pxa3xx_gpio_set_direction(int gpio_id , int dir)
118 //////////////////////////////////////////////////////////
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 *);
128 struct device *dev; /*!< device model stuff */
139 invert the endianness of a single 32it integer
141 \param[in] u: word to invert
143 \return the inverted word
145 static inline u32 invert_bo(u32 u)
147 return ((u & 0xff) << 24) | ((u & 0xff00) << 8) | ((u & 0xff0000) >> 8)
148 | ((u & 0xff000000) >> 24);
152 invert the endianness of a data buffer
154 \param[in] buf: buffer to invert
155 \param[in] len: buffer length
157 \return the inverted word
160 static int invert_endianness(char *buf, int len)
163 u32 *ptr = (u32 *) buf;
166 for (i = 0; i < len; i++, ptr++)
167 *ptr = invert_bo(*ptr);
169 return 4 * ((len + 3) & (~3));
172 /*! Map DMA buffers when request starts
176 static unsigned long dma_map_buf(struct spiphy_dev_s *spiphy_dev, char *buf,
177 int len, int direction)
179 unsigned long phyaddr; /* map dma buffers */
181 PERROR(" NULL buffers to map\n");
186 phyaddr = dma_map_single(spiphy_dev->dev, buf, len, direction);
187 if (dma_mapping_error(phyaddr)) {
188 PERROR("exiting with error\n");
195 static irqreturn_t spibus_interrupt(int irq, void *context)
197 struct spiphy_dev_s *spiphy_dev = (struct spiphy_dev_s *) context;
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);
205 if (spiphy_dev->interruptHandler)
206 spiphy_dev->interruptHandler(spiphy_dev->intr_context);
212 /*! DMA controller callback - called only on BUS error condition
214 \param[in] channel: DMA channel with error
215 \param[in] data: Unused
216 \param[in] regs: Unused
220 //extern dma_addr_t common_buf_end ;
222 static void spibus_dma_handler(int channel, void *context)
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)
233 struct spiphy_dev_s *spiphy_dev = (struct spiphy_dev_s *) context;
234 unsigned char *temp = NULL;
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);
243 if ((rxbuf)&&(len != 16))
244 ret = spi_read(spiphy_dev->Smsdevice, rxbuf, len);
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);
253 if ((rxbuf)&&(len != 16))
254 ret = spi_read(spiphy_dev->Smsdevice, rxbuf, len);
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]);
262 void smschipreset(void *context)
267 static struct ssp_state sms_ssp_state ;
269 void smsspibus_ssp_suspend(void* context )
271 struct spiphy_dev_s *spiphy_dev ;
273 sms_info("entering smsspibus_ssp_suspend\n");
277 sms_info("smsspibus_ssp_suspend context NULL \n") ;
280 spiphy_dev = (struct spiphy_dev_s *) context;
282 // free_irq(gpio_to_irq(CMMB_1186_SPIIRQ), NULL);
287 static void chip_poweron()
290 #ifdef CONFIG_MACH_LC6830_PHONE_BOARD_1_0
291 gpio_direction_output(mfp_to_gpio(MFP_PIN_GPIO4), 1);
293 gpio_direction_output(mfp_to_gpio(MFP_PIN_GPIO6), 1);
295 #elif defined CONFIG_MACH_LC6830_PHONE_BOARD_1_1
296 gpio_direction_output(mfp_to_gpio(MFP_PIN_GPIO6), 1);
298 gpio_direction_output(mfp_to_gpio(MFP_PIN_GPIO8), 1);
300 gpio_direction_output(mfp_to_gpio(MFP_PIN_GPIO4), 1);
308 //set the SPI CS mode , zyc
309 //rk2818_mux_api_set(GPIOB4_SPI0CS0_MMC0D4_NAME,1);
311 gpio_direction_output(CMMB_1186_POWER_RESET,0);
312 gpio_direction_output(CMMB_1186_POWER_DOWN,0);
314 // GPIOSetPinDirection(CMMB_1186_POWER_ENABLE,1);
315 gpio_direction_output(CMMB_1186_POWER_ENABLE,0);
317 gpio_direction_output(CMMB_1186_POWER_ENABLE,1);
320 gpio_direction_output(CMMB_1186_POWER_DOWN,1);
322 gpio_direction_output(CMMB_1186_POWER_RESET,1);
325 printk("cmmb chip_poweron !!!!\n");
328 static void chip_powerdown()
331 #ifdef CONFIG_MACH_LC6830_PHONE_BOARD_1_0
332 gpio_direction_output(mfp_to_gpio(MFP_PIN_GPIO4), 0);
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);
338 gpio_direction_output(mfp_to_gpio(MFP_PIN_GPIO8), 0);
340 gpio_direction_output(mfp_to_gpio(MFP_PIN_GPIO6), 0);
348 //1186 cmmb power down
350 // GPIOSetPinDirection(CMMB_1186_POWER_ENABLE,1);
351 gpio_direction_output(CMMB_1186_POWER_ENABLE,0);
353 //set the CS0 as gpio mode
355 // rk2818_mux_api_set(GPIOB4_SPI0CS0_MMC0D4_NAME,0);
356 // gpio_direction_output(GPIOB4_SPI0CS0_MMC0D4_NAME,0);
358 printk("cmmb chip_powerdown !!!!\n");
365 int smsspibus_ssp_resume(void* context)
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");
373 PERROR("smsspibus_ssp_resume context NULL \n");
376 spiphy_dev = (struct spiphy_dev_s *) context;
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);
384 printk("siano1186 request irq failed !!\n");
390 free_irq(gpio_to_irq(CMMB_1186_SPIIRQ), NULL);
394 void *smsspiphy_init(void *context, void (*smsspi_interruptHandler) (void *),
398 struct spiphy_dev_s *spiphy_dev;
399 u32 mode = 0, flags = 0, psp_flags = 0, speed = 0;
402 sms_debug("smsspiphy_init\n");
404 spiphy_dev = kmalloc(sizeof(struct spiphy_dev_s), GFP_KERNEL);
407 sms_err("spiphy_dev is null in smsspiphy_init\n") ;
412 spiphy_dev->interruptHandler = smsspi_interruptHandler;
413 spiphy_dev->intr_context = intr_context;
414 spiphy_dev->Smsdevice = (struct spi_device*)context;
416 //gpio_pull_updown(CMMB_1186_SPIIRQ, IRQT_FALLING);
417 //ÉèÖÃCMMB ÖжϽÅIOMUX
419 rk2818_mux_api_set(GPIOA6_FLASHCS2_SEL_NAME, 0);
420 error = gpio_request(CMMB_1186_SPIIRQ,"cmmb irq");
422 //dev_err(&pdev->dev, "failed to request play key gpio\n");
424 printk("gpio request error\n");
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#
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);
465 printk("siano 1186 request irq failed !!\n");
470 atomic_notifier_chain_register(&panic_notifier_list,&sms_panic_notifier);
471 //panic_sspdev = &(spiphy_dev->sspdev) ;
478 free_irq(gpio_to_irq(CMMB_1186_SPIIRQ), spiphy_dev);
482 int smsspiphy_deinit(void *context)
484 struct spiphy_dev_s *spiphy_dev = (struct spiphy_dev_s *) context;
485 PDEBUG("entering\n");
487 printk("entering smsspiphy_deinit\n");
490 atomic_notifier_chain_unregister(&panic_notifier_list,
491 &sms_panic_notifier);
493 sms_info("exiting\n");
494 free_irq(gpio_to_irq(CMMB_1186_SPIIRQ), spiphy_dev);
495 gpio_free(CMMB_1186_SPIIRQ);
499 void smsspiphy_set_config(struct spiphy_dev_s *spiphy_dev, int clock_divider)
504 void prepareForFWDnl(void *context)
506 struct spiphy_dev_s *spiphy_dev = (struct spiphy_dev_s *) context;
507 smsspiphy_set_config(spiphy_dev, 3);
511 void fwDnlComplete(void *context, int App)
513 struct spiphy_dev_s *spiphy_dev = (struct spiphy_dev_s *) context;
514 smsspiphy_set_config(spiphy_dev, 1);