static void broacast_tdmb_spi_work(struct work_struct *tdmb_work) { struct tdmb_t3a00_ctrl_blk *t3a00_info_p; t3a00_info_p = container_of(tdmb_work, struct tdmb_t3a00_ctrl_blk, spi_work); if ( t3a00_info_p ) { t3a00_info_p->irq_status = TRUE; broadcast_drv_if_read_data(); t3a00_info_p->irq_status = FALSE; } else { printk("~~~~~~~broadcast_tdmb_spi_work call but t3a00_info_p is NULL ~~~~~~~\n"); } }
static irqreturn_t broadcast_tdmb_spi_event_handler(int irq, void *handle) { struct tdmb_t3a00_ctrl_blk *t3a00_info_p; t3a00_info_p = (struct tdmb_t3a00_ctrl_blk *)handle; if ( t3a00_info_p && t3a00_info_p->is_power_on ) { if (t3a00_info_p->irq_status) { printk("######### spi read function is so late skip ignore #########\n"); return IRQ_HANDLED; } t3a00_info_p->irq_status = TRUE; broadcast_drv_if_read_data(); t3a00_info_p->irq_status = FALSE; } else { printk("broadcast_tdmb_spi_isr is called, but device is off state\n"); } return IRQ_HANDLED; }
int tdmb_lg2102_spi_write_read(uint8* tx_data, int tx_length, uint8 *rx_data, int rx_length) { int rc; struct spi_transfer t = { .tx_buf = tx_data, .rx_buf = rx_data, .len = tx_length+rx_length, }; struct spi_message m; if (lg2102_ctrl_info.spi_ptr == NULL) { printk("tdmb_lg2102_spi_write_read error txdata=0x%x, length=%d\n", (unsigned int)tx_data, tx_length+rx_length); return FALSE; } mutex_lock(&lg2102_ctrl_info.mutex); spi_message_init(&m); spi_message_add_tail(&t, &m); rc = spi_sync(lg2102_ctrl_info.spi_ptr, &m); if ( rc < 0 ) { printk("tdmb_lg2102_spi_read_burst result(%d), actual_len=%d\n",rc, m.actual_length); } mutex_unlock(&lg2102_ctrl_info.mutex); return TRUE; } static irqreturn_t broadcast_tdmb_spi_isr(int irq, void *handle) { struct tdmb_lg2102_ctrl_blk* pTdmbInfo; unsigned long flag; pTdmbInfo = (struct tdmb_lg2102_ctrl_blk *)handle; if ( pTdmbInfo && pTdmbInfo->TdmbPowerOnState ) { if (pTdmbInfo->spi_irq_status) { printk("########### DMB SPI ISR but funtion is so late skip ###########\n"); return IRQ_HANDLED; } spin_lock_irqsave(&pTdmbInfo->spin_lock, flag); queue_work(pTdmbInfo->spi_wq, &pTdmbInfo->spi_work); spin_unlock_irqrestore(&pTdmbInfo->spin_lock, flag); } else { printk("broadcast_tdmb_spi_isr is called, but device is off state\n"); } return IRQ_HANDLED; } static void broacast_tdmb_spi_work(struct work_struct *tdmb_work) { struct tdmb_lg2102_ctrl_blk *pTdmbWorkData; pTdmbWorkData = container_of(tdmb_work, struct tdmb_lg2102_ctrl_blk, spi_work); if ( pTdmbWorkData ) { pTdmbWorkData->spi_irq_status = TRUE; broadcast_drv_if_read_data(); pTdmbWorkData->spi_irq_status = FALSE; } } static int broadcast_tdmb_lg2102_probe(struct spi_device *spi) { int rc; lg2102_ctrl_info.spi_ptr = spi; lg2102_ctrl_info.spi_ptr->mode = SPI_MODE_0; lg2102_ctrl_info.spi_ptr->bits_per_word = 8; lg2102_ctrl_info.spi_ptr->max_speed_hz = (6000*1000); lg2102_ctrl_info.spi_ptr->irq = TEGRA_GPIO_TO_IRQ(118); rc = spi_setup(spi); INIT_WORK(&lg2102_ctrl_info.spi_work, broacast_tdmb_spi_work); lg2102_ctrl_info.spi_wq = create_singlethread_workqueue("tdmb_spi_wq"); if(lg2102_ctrl_info.spi_wq == NULL){ printk("Failed to setup tdmb spi workqueue \n"); } gpio_request(DMB_RESET_N, "dmb reset"); gpio_request(DMB_EN, "dmb enable"); gpio_request(DMB_INT_N, "dmb interrupt"); gpio_request(DMB_EARANT, "dmb earantenna"); tegra_gpio_enable(DMB_INT_N); tegra_gpio_enable(DMB_RESET_N); tegra_gpio_enable(DMB_EN); tegra_gpio_enable(DMB_EARANT); // Setting the ON/OFF pin to output mode and setting to Low. gpio_direction_output(DMB_RESET_N, 0); gpio_direction_output(DMB_EN, 0); gpio_direction_output(DMB_EARANT, 0); gpio_set_value(DMB_RESET_N, 0); gpio_set_value(DMB_EN, 0); gpio_set_value(DMB_EARANT, 0); rc = request_irq(lg2102_ctrl_info.spi_ptr->irq, broadcast_tdmb_spi_isr, IRQF_DISABLED|IRQF_TRIGGER_FALLING , lg2102_ctrl_info.spi_ptr->dev.driver->name, &lg2102_ctrl_info); printk("broadcast_tdmb_lg2102_probe request_irq=%d\n", rc); tdmb_lg2102_interrupt_lock(); mutex_init(&lg2102_ctrl_info.mutex); wake_lock_init(&lg2102_ctrl_info.wake_lock, WAKE_LOCK_SUSPEND, dev_name(&spi->dev)); spin_lock_init(&lg2102_ctrl_info.spin_lock); pm_qos_add_request(&lg2102_ctrl_info.pm_req_list, PM_QOS_CPU_DMA_LATENCY, PM_QOS_DEFAULT_VALUE); printk("[lg2102_probe] probe complete"); return rc; }