int tdmb_fc8050_power_off(void) { if ( fc8050_ctrl_info.TdmbPowerOnState == TRUE ) { tdmb_fc8050_interrupt_lock(); fc8050_ctrl_info.TdmbPowerOnState = FALSE; gpio_set_value(DMB_RESET_N, 0); gpio_set_value(DMB_EN, 0); //gpio_direction_output(DMB_INT_N, false); gpio_set_value(DMB_INT_N, 0); #ifdef ANTENNA_SWITCHING gpio_set_value_cansleep(DMB_ANT_SEL_P_EAR, 1); gpio_set_value_cansleep(DMB_ANT_SEL_N_INNER, 0); #endif /* ANTENNA_SWITCHING */ wake_unlock(&fc8050_ctrl_info.wake_lock); #ifdef PM_QOS /* QoS release */ if(pm_qos_request_active(&fc8050_ctrl_info.pm_req_list)) { pm_qos_update_request(&fc8050_ctrl_info.pm_req_list, PM_QOS_DEFAULT_VALUE); } #endif } else { printk("tdmb_fc8050_power_on the power already turn off \n"); } printk("tdmb_fc8050_power_off completed \n"); return TRUE; }
int tdmb_fc8050_power_off(void) { if ( fc8050_ctrl_info.TdmbPowerOnState == TRUE ) { tdmb_fc8050_interrupt_lock(); if(xo_handle_tdmb != NULL) { msm_xo_mode_vote(xo_handle_tdmb, MSM_XO_MODE_OFF); } fc8050_ctrl_info.TdmbPowerOnState = FALSE; gpio_set_value(DMB_RESET_N, 0); gpio_set_value(DMB_EN, 0); wake_unlock(&fc8050_ctrl_info.wake_lock); /* if(pm_qos_request_active(&fc8050_ctrl_info.pm_req_list)) { pm_qos_update_request(&fc8050_ctrl_info.pm_req_list, PM_QOS_DEFAULT_VALUE); }*/ } else { printk("tdmb_fc8050_power_on the power already turn off \n"); } printk("tdmb_fc8050_power_off completed \n"); return TRUE; }
static int broadcast_tdmb_fc8050_probe(struct spi_device *spi) { int rc; fc8050_ctrl_info.TdmbPowerOnState = FALSE; fc8050_ctrl_info.spi_ptr = spi; fc8050_ctrl_info.spi_ptr->mode = SPI_MODE_0; fc8050_ctrl_info.spi_ptr->bits_per_word = 8; fc8050_ctrl_info.spi_ptr->max_speed_hz = (24000*1000); rc = spi_setup(spi); printk("broadcast_tdmb_fc8050_probe spi_setup=%d\n", rc); BBM_HOSTIF_SELECT(NULL, 1); xo_handle_tdmb = msm_xo_get(MSM_XO_TCXO_A2, id); if(IS_ERR(xo_handle_tdmb)) { pr_err("Failed to get MSM_XO_TCXO_A2 handle for TDMB (%ld)\n", PTR_ERR(xo_handle_tdmb)); return FALSE; } #ifdef FEATURE_DMB_USE_WORKQUEUE INIT_WORK(&fc8050_ctrl_info.spi_work, broacast_tdmb_spi_work); fc8050_ctrl_info.spi_wq = create_singlethread_workqueue("tdmb_spi_wq"); if(fc8050_ctrl_info.spi_wq == NULL){ printk("Failed to setup tdmb spi workqueue \n"); return -ENOMEM; } #endif tdmb_configure_gpios( ); #ifdef FEATURE_DMB_USE_WORKQUEUE rc = request_irq(spi->irq, broadcast_tdmb_spi_isr, IRQF_DISABLED | IRQF_TRIGGER_FALLING, spi->dev.driver->name, &fc8050_ctrl_info); #else rc = request_threaded_irq(spi->irq, NULL, broadcast_tdmb_spi_event_handler, IRQF_DISABLED | IRQF_TRIGGER_FALLING, spi->dev.driver->name, &fc8050_ctrl_info); #endif printk("broadcast_tdmb_fc8050_probe request_irq=%d\n", rc); tdmb_fc8050_interrupt_lock(); mutex_init(&fc8050_ctrl_info.mutex); wake_lock_init(&fc8050_ctrl_info.wake_lock, WAKE_LOCK_SUSPEND, dev_name(&spi->dev)); spin_lock_init(&fc8050_ctrl_info.spin_lock); // pm_qos_add_request(&fc8050_ctrl_info.pm_req_list, PM_QOS_CPU_DMA_LATENCY, PM_QOS_DEFAULT_VALUE); printk("broadcast_fc8050_probe End\n"); return rc; }
int tdmb_fc8050_power_off(void) { if ( fc8050_ctrl_info.TdmbPowerOnState == TRUE ) { tdmb_fc8050_interrupt_lock(); #ifdef FEATURE_DMB_USE_XO if(fc8050_ctrl_info.clk != NULL) { clk_disable_unprepare(fc8050_ctrl_info.clk); } #endif fc8050_ctrl_info.TdmbPowerOnState = FALSE; gpio_set_value(DMB_RESET_N, 0); gpio_set_value(DMB_EN, 0); wake_unlock(&fc8050_ctrl_info.wake_lock); // gpio_set_value(PM8058_GPIO_PM_TO_SYS(DMB_ANT_SEL_P-1), 1); // for ESD TEST // gpio_set_value(PM8058_GPIO_PM_TO_SYS(DMB_ANT_SEL_N-1), 0); #ifdef FEATURE_DMB_USE_BUS_SCALE msm_bus_scale_client_update_request(fc8050_ctrl_info.bus_scale_client_id, 0); /* expensive call, index:0 is the <84 512 0 0> entry */ #endif #ifdef FEATURE_DMB_USE_PM_QOS if(pm_qos_request_active(&fc8050_ctrl_info.pm_req_list)) { pm_qos_update_request(&fc8050_ctrl_info.pm_req_list, PM_QOS_DEFAULT_VALUE); } #endif } else { printk("tdmb_fc8050_power_on the power already turn off \n"); } printk("tdmb_fc8050_power_off completed \n"); return TRUE; }
int tdmb_fc8050_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 (fc8050_ctrl_info.spi_ptr == NULL) { printk("tdmb_fc8050_spi_write_read error txdata=0x%x, length=%d\n", (unsigned int)tx_data, tx_length+rx_length); } mutex_lock(&fc8050_ctrl_info.mutex); spi_message_init(&m); spi_message_add_tail(&t, &m); rc = spi_sync(fc8050_ctrl_info.spi_ptr, &m); if ( rc < 0 ) { printk("tdmb_fc8050_spi_read_burst result(%d), actual_len=%d\n",rc, m.actual_length); } mutex_unlock(&fc8050_ctrl_info.mutex); return TRUE; } #ifdef FEATURE_DMB_USE_WORKQUEUE static irqreturn_t broadcast_tdmb_spi_isr(int irq, void *handle) { struct tdmb_fc8050_ctrl_blk* fc8050_info_p; unsigned long flag; fc8050_info_p = (struct tdmb_fc8050_ctrl_blk *)handle; if ( fc8050_info_p && fc8050_info_p->TdmbPowerOnState ) { if (fc8050_info_p->spi_irq_status) { printk("######### spi read function is so late skip #########\n"); return IRQ_HANDLED; } // printk("***** broadcast_tdmb_spi_isr coming *******\n"); spin_lock_irqsave(&fc8050_info_p->spin_lock, flag); queue_work(fc8050_info_p->spi_wq, &fc8050_info_p->spi_work); spin_unlock_irqrestore(&fc8050_info_p->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_fc8050_ctrl_blk *pTdmbWorkData; pTdmbWorkData = container_of(tdmb_work, struct tdmb_fc8050_ctrl_blk, spi_work); if ( pTdmbWorkData ) { fc8050_isr_control(0); pTdmbWorkData->spi_irq_status = TRUE; broadcast_drv_if_isr(); pTdmbWorkData->spi_irq_status = FALSE; fc8050_isr_control(1); } else { printk("~~~~~~~broadcast_tdmb_spi_work call but pTdmbworkData is NULL ~~~~~~~\n"); } } #else static irqreturn_t broadcast_tdmb_spi_event_handler(int irq, void *handle) { struct tdmb_fc8050_ctrl_blk* fc8050_info_p; fc8050_info_p = (struct tdmb_fc8050_ctrl_blk *)handle; if ( fc8050_info_p && fc8050_info_p->TdmbPowerOnState ) { if (fc8050_info_p->spi_irq_status) { printk("######### spi read function is so late skip #########\n"); return IRQ_HANDLED; } fc8050_isr_control(0); fc8050_info_p->spi_irq_status = TRUE; broadcast_drv_if_isr(); fc8050_info_p->spi_irq_status = FALSE; fc8050_isr_control(1); } else { printk("broadcast_tdmb_spi_isr is called, but device is off state\n"); } return IRQ_HANDLED; } #endif static int broadcast_tdmb_fc8050_probe(struct spi_device *spi) { int rc; #ifdef ANTENNA_SWITCHING struct pm_gpio GPIO11_CFG = { .direction = PM_GPIO_DIR_OUT, .pull = PM_GPIO_PULL_NO, .function = PM_GPIO_FUNC_NORMAL, .vin_sel = 2, .inv_int_pol = 0, }; struct pm_gpio GPIO12_CFG = { .direction = PM_GPIO_DIR_OUT, .pull = PM_GPIO_PULL_NO, .function = PM_GPIO_FUNC_NORMAL, .vin_sel = 2, .inv_int_pol = 0, }; #endif /* ANTENNA_SWITCHING */ fc8050_ctrl_info.TdmbPowerOnState = FALSE; fc8050_ctrl_info.spi_ptr = spi; fc8050_ctrl_info.spi_ptr->mode = SPI_MODE_0; fc8050_ctrl_info.spi_ptr->bits_per_word = 8; fc8050_ctrl_info.spi_ptr->max_speed_hz = ( 24000*1000 ); rc = spi_setup(spi); printk("broadcast_tdmb_fc8050_probe spi_setup=%d\n", rc); BBM_HOSTIF_SELECT(NULL, 1); #ifdef FEATURE_DMB_USE_WORKQUEUE INIT_WORK(&fc8050_ctrl_info.spi_work, broacast_tdmb_spi_work); fc8050_ctrl_info.spi_wq = create_singlethread_workqueue("tdmb_spi_wq"); if(fc8050_ctrl_info.spi_wq == NULL){ printk("Failed to setup tdmb spi workqueue \n"); return -ENOMEM; } #endif gpio_request(DMB_RESET_N, "DMB_RESET_N"); gpio_request(DMB_EN, "DMB_EN"); gpio_request(DMB_INT_N, "DMB_INT_N"); //gpio_direction_output(DMB_RESET_N, false); //gpio_direction_output(DMB_EN, false); //gpio_direction_output(DMB_INT_N, false); #ifdef ANTENNA_SWITCHING pm8xxx_gpio_config(DMB_ANT_SEL_P_EAR, &GPIO11_CFG); pm8xxx_gpio_config(DMB_ANT_SEL_N_INNER, &GPIO12_CFG); gpio_set_value_cansleep(DMB_ANT_SEL_P_EAR, 1); gpio_set_value_cansleep(DMB_ANT_SEL_N_INNER, 0); #endif /* ANTENNA_SWITCHING */ #ifdef FEATURE_DMB_USE_WORKQUEUE rc = request_irq(spi->irq, broadcast_tdmb_spi_isr, IRQF_DISABLED | IRQF_TRIGGER_FALLING, spi->dev.driver->name, &fc8050_ctrl_info); #else rc = request_threaded_irq(spi->irq, NULL, broadcast_tdmb_spi_event_handler, IRQF_DISABLED | IRQF_TRIGGER_FALLING, spi->dev.driver->name, &fc8050_ctrl_info); #endif printk("broadcast_tdmb_fc8050_probe request_irq=%d\n", rc); tdmb_fc8050_interrupt_lock(); mutex_init(&fc8050_ctrl_info.mutex); wake_lock_init(&fc8050_ctrl_info.wake_lock, WAKE_LOCK_SUSPEND, dev_name(&spi->dev)); spin_lock_init(&fc8050_ctrl_info.spin_lock); #ifdef PM_QOS pm_qos_add_request(&fc8050_ctrl_info.pm_req_list, PM_QOS_CPU_DMA_LATENCY, PM_QOS_DEFAULT_VALUE); #endif /* PM_QOS */ printk("broadcast_fc8050_probe End\n"); return rc; } static int broadcast_tdmb_fc8050_remove(struct spi_device *spi) { printk("broadcast_tdmb_fc8050_remove \n"); #ifdef FEATURE_DMB_USE_WORKQUEUE if (fc8050_ctrl_info.spi_wq) { flush_workqueue(fc8050_ctrl_info.spi_wq); destroy_workqueue(fc8050_ctrl_info.spi_wq); } #endif free_irq(spi->irq, &fc8050_ctrl_info); mutex_destroy(&fc8050_ctrl_info.mutex); wake_lock_destroy(&fc8050_ctrl_info.wake_lock); #ifdef PM_QOS pm_qos_remove_request(&fc8050_ctrl_info.pm_req_list); #endif /* PM_QOS */ memset((unsigned char*)&fc8050_ctrl_info, 0x0, sizeof(struct tdmb_fc8050_ctrl_blk)); return 0; } static int broadcast_tdmb_fc8050_suspend(struct spi_device *spi, pm_message_t mesg) { printk("broadcast_tdmb_fc8050_suspend \n"); return 0; }
static int broadcast_tdmb_fc8050_probe(struct spi_device *spi) { int rc; if(spi == NULL) { printk("broadcast_fc8050_probe spi is NULL, so spi can not be set\n"); return -1; } fc8050_ctrl_info.TdmbPowerOnState = FALSE; fc8050_ctrl_info.spi_ptr = spi; fc8050_ctrl_info.spi_ptr->mode = SPI_MODE_0; fc8050_ctrl_info.spi_ptr->bits_per_word = 8; fc8050_ctrl_info.spi_ptr->max_speed_hz = (15000*1000); #ifdef FEATURE_DMB_USE_BUS_SCALE fc8050_ctrl_info.pdev = to_platform_device(&spi->dev); fc8050_ctrl_info.bus_scale_pdata = msm_bus_cl_get_pdata(fc8050_ctrl_info.pdev); fc8050_ctrl_info.bus_scale_client_id = msm_bus_scale_register_client(fc8050_ctrl_info.bus_scale_pdata); #endif // Once I have a spi_device structure I can do a transfer anytime rc = spi_setup(spi); printk("broadcast_tdmb_fc8050_probe spi_setup=%d\n", rc); BBM_HOSTIF_SELECT(NULL, 1); #ifdef FEATURE_DMB_USE_XO fc8050_ctrl_info.clk = clk_get(&fc8050_ctrl_info.spi_ptr->dev, "xo"); if (IS_ERR(fc8050_ctrl_info.clk)) { rc = PTR_ERR(fc8050_ctrl_info.clk); dev_err(&fc8050_ctrl_info.spi_ptr->dev, "could not get clock\n"); return rc; } /* We enable/disable the clock only to assure it works */ rc = clk_prepare_enable(fc8050_ctrl_info.clk); if (rc) { dev_err(&fc8050_ctrl_info.spi_ptr->dev, "could not enable clock\n"); return rc; } clk_disable_unprepare(fc8050_ctrl_info.clk); #endif #ifdef FEATURE_DMB_USE_WORKQUEUE INIT_WORK(&fc8050_ctrl_info.spi_work, broacast_tdmb_spi_work); fc8050_ctrl_info.spi_wq = create_singlethread_workqueue("tdmb_spi_wq"); if(fc8050_ctrl_info.spi_wq == NULL){ printk("Failed to setup tdmb spi workqueue \n"); return -ENOMEM; } #endif tdmb_configure_gpios(); #ifdef FEATURE_DMB_USE_WORKQUEUE rc = request_irq(spi->irq, broadcast_tdmb_spi_isr, IRQF_DISABLED | IRQF_TRIGGER_FALLING, spi->dev.driver->name, &fc8050_ctrl_info); #else rc = request_threaded_irq(spi->irq, NULL, broadcast_tdmb_spi_event_handler, IRQF_ONESHOT | IRQF_DISABLED | IRQF_TRIGGER_FALLING, spi->dev.driver->name, &fc8050_ctrl_info); #endif printk("broadcast_tdmb_fc8050_probe request_irq=%d\n", rc); tdmb_fc8050_interrupt_lock(); mutex_init(&fc8050_ctrl_info.mutex); wake_lock_init(&fc8050_ctrl_info.wake_lock, WAKE_LOCK_SUSPEND, dev_name(&spi->dev)); spin_lock_init(&fc8050_ctrl_info.spin_lock); #ifdef FEATURE_DMB_USE_PM_QOS pm_qos_add_request(&fc8050_ctrl_info.pm_req_list, PM_QOS_CPU_DMA_LATENCY, PM_QOS_DEFAULT_VALUE); #endif printk("broadcast_fc8050_probe End\n"); return rc; }