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 //#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
49 /*! macro to align the divider to the proper offset in the register bits */
50 #define CLOCK_DIVIDER(i)((i-1)<<8) /* 1-4096 */
53 #define SPI_PACKET_SIZE 256
56 unsigned long u_irq_count =0;
58 static unsigned int dma_rxbuf_phy_addr ;
59 static unsigned int dma_txbuf_phy_addr ;
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 ;
66 static struct ssp_dev* panic_sspdev = NULL ;
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);
74 static int sms_panic_handler(struct notifier_block *this,
78 static int panic_event_handled = 0;
79 if(!panic_event_handled)
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) ;
86 panic_event_handled =1 ;
91 static struct notifier_block sms_panic_notifier = {
92 .notifier_call = sms_panic_handler,
94 .priority = 150 /* priority: INT_MAX >= x >= 0 */
100 /*! GPIO functions for PXA3xx
103 void pxa3xx_gpio_set_rising_edge_detect (int gpio_id, int dir)
110 void pxa3xx_gpio_set_direction(int gpio_id , int dir)
116 //////////////////////////////////////////////////////////
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 *);
126 struct device *dev; /*!< device model stuff */
137 invert the endianness of a single 32it integer
139 \param[in] u: word to invert
141 \return the inverted word
143 static inline u32 invert_bo(u32 u)
145 return ((u & 0xff) << 24) | ((u & 0xff00) << 8) | ((u & 0xff0000) >> 8)
146 | ((u & 0xff000000) >> 24);
150 invert the endianness of a data buffer
152 \param[in] buf: buffer to invert
153 \param[in] len: buffer length
155 \return the inverted word
158 static int invert_endianness(char *buf, int len)
161 u32 *ptr = (u32 *) buf;
164 for (i = 0; i < len; i++, ptr++)
165 *ptr = invert_bo(*ptr);
167 return 4 * ((len + 3) & (~3));
170 /*! Map DMA buffers when request starts
174 static unsigned long dma_map_buf(struct spiphy_dev_s *spiphy_dev, char *buf,
175 int len, int direction)
177 unsigned long phyaddr; /* map dma buffers */
179 PERROR(" NULL buffers to map\n");
184 phyaddr = dma_map_single(spiphy_dev->dev, buf, len, direction);
185 if (dma_mapping_error(phyaddr)) {
186 PERROR("exiting with error\n");
193 static irqreturn_t spibus_interrupt(int irq, void *context)
195 struct spiphy_dev_s *spiphy_dev = (struct spiphy_dev_s *) context;
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);
203 if (spiphy_dev->interruptHandler)
204 spiphy_dev->interruptHandler(spiphy_dev->intr_context);
210 /*! DMA controller callback - called only on BUS error condition
212 \param[in] channel: DMA channel with error
213 \param[in] data: Unused
214 \param[in] regs: Unused
218 //extern dma_addr_t common_buf_end ;
220 static void spibus_dma_handler(int channel, void *context)
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)
231 struct spiphy_dev_s *spiphy_dev = (struct spiphy_dev_s *) context;
232 unsigned char *temp = NULL;
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);
241 if ((rxbuf)&&(len != 16))
242 ret = spi_read(spiphy_dev->Smsdevice, rxbuf, len);
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);
251 if ((rxbuf)&&(len != 16))
252 ret = spi_read(spiphy_dev->Smsdevice, rxbuf, len);
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]);
260 void smschipreset(void *context)
265 static struct ssp_state sms_ssp_state ;
267 void smsspibus_ssp_suspend(void* context )
269 struct spiphy_dev_s *spiphy_dev ;
271 sms_info("entering smsspibus_ssp_suspend\n");
275 sms_info("smsspibus_ssp_suspend context NULL \n") ;
278 spiphy_dev = (struct spiphy_dev_s *) context;
280 free_irq(gpio_to_irq(CMMB_1186_SPIIRQ), NULL);
285 static void chip_poweron()
288 #ifdef CONFIG_MACH_LC6830_PHONE_BOARD_1_0
289 gpio_direction_output(mfp_to_gpio(MFP_PIN_GPIO4), 1);
291 gpio_direction_output(mfp_to_gpio(MFP_PIN_GPIO6), 1);
293 #elif defined CONFIG_MACH_LC6830_PHONE_BOARD_1_1
294 gpio_direction_output(mfp_to_gpio(MFP_PIN_GPIO6), 1);
296 gpio_direction_output(mfp_to_gpio(MFP_PIN_GPIO8), 1);
298 gpio_direction_output(mfp_to_gpio(MFP_PIN_GPIO4), 1);
306 //set the SPI CS mode , zyc
307 //rk2818_mux_api_set(GPIOB4_SPI0CS0_MMC0D4_NAME,1);
309 gpio_direction_output(CMMB_1186_POWER_RESET,0);
310 gpio_direction_output(CMMB_1186_POWER_DOWN,0);
312 // GPIOSetPinDirection(CMMB_1186_POWER_ENABLE,1);
313 gpio_direction_output(CMMB_1186_POWER_ENABLE,0);
315 gpio_direction_output(CMMB_1186_POWER_ENABLE,1);
318 gpio_direction_output(CMMB_1186_POWER_DOWN,1);
320 gpio_direction_output(CMMB_1186_POWER_RESET,1);
323 printk("cmmb chip_poweron !!!!\n");
326 static void chip_powerdown()
329 #ifdef CONFIG_MACH_LC6830_PHONE_BOARD_1_0
330 gpio_direction_output(mfp_to_gpio(MFP_PIN_GPIO4), 0);
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);
336 gpio_direction_output(mfp_to_gpio(MFP_PIN_GPIO8), 0);
338 gpio_direction_output(mfp_to_gpio(MFP_PIN_GPIO6), 0);
346 //1186 cmmb power down
348 // GPIOSetPinDirection(CMMB_1186_POWER_ENABLE,1);
349 gpio_direction_output(CMMB_1186_POWER_ENABLE,0);
351 //set the CS0 as gpio mode
353 // rk2818_mux_api_set(GPIOB4_SPI0CS0_MMC0D4_NAME,0);
354 // gpio_direction_output(GPIOB4_SPI0CS0_MMC0D4_NAME,0);
356 printk("cmmb chip_powerdown !!!!\n");
363 int smsspibus_ssp_resume(void* context)
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");
371 PERROR("smsspibus_ssp_resume context NULL \n");
374 spiphy_dev = (struct spiphy_dev_s *) context;
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);
382 printk("siano1186 request irq failed !!\n");
388 free_irq(gpio_to_irq(CMMB_1186_SPIIRQ), NULL);
393 void *smsspiphy_init(void *context, void (*smsspi_interruptHandler) (void *),
397 struct spiphy_dev_s *spiphy_dev;
398 u32 mode = 0, flags = 0, psp_flags = 0, speed = 0;
401 sms_debug("smsspiphy_init\n");
403 spiphy_dev = kmalloc(sizeof(struct spiphy_dev_s), GFP_KERNEL);
406 sms_err("spiphy_dev is null in smsspiphy_init\n") ;
410 spiphy_dev->interruptHandler = smsspi_interruptHandler;
411 spiphy_dev->intr_context = intr_context;
412 spiphy_dev->Smsdevice = (struct spi_device*)context;
414 //gpio_pull_updown(CMMB_1186_SPIIRQ, IRQT_FALLING);
415 error = gpio_request(CMMB_1186_SPIIRQ,"cmmb irq");
417 //dev_err(&pdev->dev, "failed to request play key gpio\n");
419 printk("gpio request error\n");
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);
427 printk("siano 1186 request irq failed !!\n");
432 atomic_notifier_chain_register(&panic_notifier_list,&sms_panic_notifier);
433 //panic_sspdev = &(spiphy_dev->sspdev) ;
440 free_irq(gpio_to_irq(CMMB_1186_SPIIRQ), NULL);
444 int smsspiphy_deinit(void *context)
446 struct spiphy_dev_s *spiphy_dev = (struct spiphy_dev_s *) context;
447 PDEBUG("entering\n");
449 printk("entering smsspiphy_deinit\n");
452 atomic_notifier_chain_unregister(&panic_notifier_list,
453 &sms_panic_notifier);
455 sms_info("exiting\n");
456 free_irq(gpio_to_irq(CMMB_1186_SPIIRQ), NULL);
461 void smsspiphy_set_config(struct spiphy_dev_s *spiphy_dev, int clock_divider)
466 void prepareForFWDnl(void *context)
468 struct spiphy_dev_s *spiphy_dev = (struct spiphy_dev_s *) context;
469 smsspiphy_set_config(spiphy_dev, 3);
473 void fwDnlComplete(void *context, int App)
475 struct spiphy_dev_s *spiphy_dev = (struct spiphy_dev_s *) context;
476 smsspiphy_set_config(spiphy_dev, 1);