Lines Matching +full:tx +full:- +full:freq

1 // SPDX-License-Identifier: GPL-2.0-only
5 * This sub-module of FM driver is common for FM RX and TX
7 * 1) Forming group of Channel-8 commands to perform particular
9 * one Channel-8 command to be sent to the chip).
10 * 2) Sending each Channel-8 command to the chip and reading
12 * 3) Managing TX and RX Queues and Tasklets.
14 * 5) Loading FM firmware to the chip (common, FM TX, and FM RX
64 static u32 radio_nr = -1;
115 /* TX power enable irq handler */
149 fm_irq_handle_power_enb, /* TX power enable irq handler */
173 fmdev->irq_info.handlers[fmdev->irq_info.stage](fmdev); in fm_irq_call()
179 fmdev->irq_info.stage = stage; in fm_irq_call_stage()
185 fmdev->irq_info.stage = stage; in fm_irq_timeout_stage()
186 mod_timer(&fmdev->irq_info.timer, jiffies + FM_DRV_TX_TIMEOUT); in fm_irq_timeout_stage()
190 /* To dump outgoing FM Channel-8 packets */
197 cmd_hdr = (struct fm_cmd_msg_hdr *)skb->data; in dump_tx_skb_data()
199 fm_cb(skb)->completion ? " " : "*", cmd_hdr->hdr, in dump_tx_skb_data()
200 cmd_hdr->len, cmd_hdr->op, in dump_tx_skb_data()
201 cmd_hdr->rd_wr ? "RD" : "WR", cmd_hdr->dlen); in dump_tx_skb_data()
203 len_org = skb->len - FM_CMD_MSG_HDR_SIZE; in dump_tx_skb_data()
205 printk(KERN_CONT "\n data(%d): ", cmd_hdr->dlen); in dump_tx_skb_data()
209 skb->data[FM_CMD_MSG_HDR_SIZE + index]); in dump_tx_skb_data()
215 /* To dump incoming FM Channel-8 packets */
222 evt_hdr = (struct fm_event_msg_hdr *)skb->data; in dump_rx_skb_data()
224 evt_hdr->hdr, evt_hdr->len, in dump_rx_skb_data()
225 evt_hdr->status, evt_hdr->num_fm_hci_cmds, evt_hdr->op, in dump_rx_skb_data()
226 (evt_hdr->rd_wr) ? "RD" : "WR", evt_hdr->dlen); in dump_rx_skb_data()
228 len_org = skb->len - FM_EVT_MSG_HDR_SIZE; in dump_rx_skb_data()
230 printk(KERN_CONT "\n data(%d): ", evt_hdr->dlen); in dump_rx_skb_data()
234 skb->data[FM_EVT_MSG_HDR_SIZE + index]); in dump_rx_skb_data()
243 fmdev->rx.region = region_configs[region_to_set]; in fmc_update_region_info()
247 * FM common sub-module will schedule this tasklet whenever it receives
260 irq_info = &fmdev->irq_info; in recv_tasklet()
262 while ((skb = skb_dequeue(&fmdev->rx_q))) { in recv_tasklet()
263 if (skb->len < sizeof(struct fm_event_msg_hdr)) { in recv_tasklet()
266 skb->len, sizeof(struct fm_event_msg_hdr)); in recv_tasklet()
271 evt_hdr = (void *)skb->data; in recv_tasklet()
272 num_fm_hci_cmds = evt_hdr->num_fm_hci_cmds; in recv_tasklet()
275 if (evt_hdr->op == FM_INTERRUPT) { in recv_tasklet()
277 if (!test_bit(FM_INTTASK_RUNNING, &fmdev->flag)) { in recv_tasklet()
278 set_bit(FM_INTTASK_RUNNING, &fmdev->flag); in recv_tasklet()
279 if (irq_info->stage != 0) { in recv_tasklet()
281 irq_info->stage = 0; in recv_tasklet()
288 irq_info->handlers[irq_info->stage](fmdev); in recv_tasklet()
290 set_bit(FM_INTTASK_SCHEDULE_PENDING, &fmdev->flag); in recv_tasklet()
295 else if (evt_hdr->op == fmdev->pre_op && fmdev->resp_comp != NULL) { in recv_tasklet()
297 spin_lock_irqsave(&fmdev->resp_skb_lock, flags); in recv_tasklet()
298 fmdev->resp_skb = skb; in recv_tasklet()
299 spin_unlock_irqrestore(&fmdev->resp_skb_lock, flags); in recv_tasklet()
300 complete(fmdev->resp_comp); in recv_tasklet()
302 fmdev->resp_comp = NULL; in recv_tasklet()
303 atomic_set(&fmdev->tx_cnt, 1); in recv_tasklet()
306 else if (evt_hdr->op == fmdev->pre_op && fmdev->resp_comp == NULL) { in recv_tasklet()
307 if (fmdev->resp_skb != NULL) in recv_tasklet()
310 spin_lock_irqsave(&fmdev->resp_skb_lock, flags); in recv_tasklet()
311 fmdev->resp_skb = skb; in recv_tasklet()
312 spin_unlock_irqrestore(&fmdev->resp_skb_lock, flags); in recv_tasklet()
315 irq_info->handlers[irq_info->stage](fmdev); in recv_tasklet()
318 atomic_set(&fmdev->tx_cnt, 1); in recv_tasklet()
325 * not zero, schedule FM TX tasklet. in recv_tasklet()
327 if (num_fm_hci_cmds && atomic_read(&fmdev->tx_cnt)) in recv_tasklet()
328 if (!skb_queue_empty(&fmdev->tx_q)) in recv_tasklet()
329 tasklet_schedule(&fmdev->tx_task); in recv_tasklet()
342 if (!atomic_read(&fmdev->tx_cnt)) in send_tasklet()
346 if (time_is_before_jiffies(fmdev->last_tx_jiffies + FM_DRV_TX_TIMEOUT)) { in send_tasklet()
347 fmerr("TX timeout occurred\n"); in send_tasklet()
348 atomic_set(&fmdev->tx_cnt, 1); in send_tasklet()
351 /* Send queued FM TX packets */ in send_tasklet()
352 skb = skb_dequeue(&fmdev->tx_q); in send_tasklet()
356 atomic_dec(&fmdev->tx_cnt); in send_tasklet()
357 fmdev->pre_op = fm_cb(skb)->fm_op; in send_tasklet()
359 if (fmdev->resp_comp != NULL) in send_tasklet()
362 fmdev->resp_comp = fm_cb(skb)->completion; in send_tasklet()
368 fmdev->resp_comp = NULL; in send_tasklet()
369 fmerr("TX tasklet failed to send skb(%p)\n", skb); in send_tasklet()
370 atomic_set(&fmdev->tx_cnt, 1); in send_tasklet()
372 fmdev->last_tx_jiffies = jiffies; in send_tasklet()
377 * Queues FM Channel-8 packet to FM TX queue and schedules FM TX tasklet for
388 fmerr("Invalid fm opcode - %d\n", fm_op); in fm_send_cmd()
389 return -EINVAL; in fm_send_cmd()
391 if (test_bit(FM_FW_DW_INPROGRESS, &fmdev->flag) && payload == NULL) { in fm_send_cmd()
393 return -EINVAL; in fm_send_cmd()
395 if (!test_bit(FM_FW_DW_INPROGRESS, &fmdev->flag)) in fm_send_cmd()
404 return -ENOMEM; in fm_send_cmd()
410 if (!test_bit(FM_FW_DW_INPROGRESS, &fmdev->flag) || in fm_send_cmd()
411 test_bit(FM_INTTASK_RUNNING, &fmdev->flag)) { in fm_send_cmd()
414 hdr->hdr = FM_PKT_LOGICAL_CHAN_NUMBER; /* 0x08 */ in fm_send_cmd()
417 hdr->len = ((payload == NULL) ? 0 : payload_len) + 3; in fm_send_cmd()
420 hdr->op = fm_op; in fm_send_cmd()
423 hdr->rd_wr = type; in fm_send_cmd()
424 hdr->dlen = payload_len; in fm_send_cmd()
425 fm_cb(skb)->fm_op = fm_op; in fm_send_cmd()
429 * not a read command then payload is != NULL - a write in fm_send_cmd()
430 * command with u16 payload - convert to be16 in fm_send_cmd()
436 fm_cb(skb)->fm_op = *((u8 *)payload + 2); in fm_send_cmd()
441 fm_cb(skb)->completion = wait_completion; in fm_send_cmd()
442 skb_queue_tail(&fmdev->tx_q, skb); in fm_send_cmd()
443 tasklet_schedule(&fmdev->tx_task); in fm_send_cmd()
448 /* Sends FM Channel-8 command to the chip and waits for the response */
457 init_completion(&fmdev->maintask_comp); in fmc_send_cmd()
459 &fmdev->maintask_comp); in fmc_send_cmd()
463 if (!wait_for_completion_timeout(&fmdev->maintask_comp, in fmc_send_cmd()
467 return -ETIMEDOUT; in fmc_send_cmd()
469 spin_lock_irqsave(&fmdev->resp_skb_lock, flags); in fmc_send_cmd()
470 if (!fmdev->resp_skb) { in fmc_send_cmd()
471 spin_unlock_irqrestore(&fmdev->resp_skb_lock, flags); in fmc_send_cmd()
473 return -EFAULT; in fmc_send_cmd()
475 skb = fmdev->resp_skb; in fmc_send_cmd()
476 fmdev->resp_skb = NULL; in fmc_send_cmd()
477 spin_unlock_irqrestore(&fmdev->resp_skb_lock, flags); in fmc_send_cmd()
479 evt_hdr = (void *)skb->data; in fmc_send_cmd()
480 if (evt_hdr->status != 0) { in fmc_send_cmd()
482 evt_hdr->status); in fmc_send_cmd()
484 return -EIO; in fmc_send_cmd()
487 if (response != NULL && response_len != NULL && evt_hdr->dlen && in fmc_send_cmd()
488 evt_hdr->dlen <= payload_len) { in fmc_send_cmd()
491 memcpy(response, skb->data, evt_hdr->dlen); in fmc_send_cmd()
492 *response_len = evt_hdr->dlen; in fmc_send_cmd()
493 } else if (response_len != NULL && evt_hdr->dlen == 0) { in fmc_send_cmd()
501 /* --- Helper functions used in FM interrupt handlers ---*/
508 del_timer(&fmdev->irq_info.timer); in check_cmdresp_status()
510 spin_lock_irqsave(&fmdev->resp_skb_lock, flags); in check_cmdresp_status()
511 *skb = fmdev->resp_skb; in check_cmdresp_status()
512 fmdev->resp_skb = NULL; in check_cmdresp_status()
513 spin_unlock_irqrestore(&fmdev->resp_skb_lock, flags); in check_cmdresp_status()
515 fm_evt_hdr = (void *)(*skb)->data; in check_cmdresp_status()
516 if (fm_evt_hdr->status != 0) { in check_cmdresp_status()
518 fm_evt_hdr->op); in check_cmdresp_status()
520 mod_timer(&fmdev->irq_info.timer, jiffies + FM_DRV_TX_TIMEOUT); in check_cmdresp_status()
521 return -1; in check_cmdresp_status()
539 * interrupt process. Therefore reset stage index to re-enable default
547 fmdbg("irq: timeout,trying to re-enable fm interrupts\n"); in int_timeout_handler()
549 fmirq = &fmdev->irq_info; in int_timeout_handler()
550 fmirq->retry++; in int_timeout_handler()
552 if (fmirq->retry > FM_IRQ_TIMEOUT_RETRY_MAX) { in int_timeout_handler()
555 fmirq->stage = 0; in int_timeout_handler()
556 fmirq->retry = 0; in int_timeout_handler()
563 /* --------- FM interrupt handlers ------------*/
581 fm_evt_hdr = (void *)skb->data; in fm_irq_handle_flag_getcmd_resp()
582 if (fm_evt_hdr->dlen > sizeof(fmdev->irq_info.flag)) in fm_irq_handle_flag_getcmd_resp()
587 memcpy(&fmdev->irq_info.flag, skb->data, fm_evt_hdr->dlen); in fm_irq_handle_flag_getcmd_resp()
589 fmdev->irq_info.flag = be16_to_cpu((__force __be16)fmdev->irq_info.flag); in fm_irq_handle_flag_getcmd_resp()
590 fmdbg("irq: flag register(0x%x)\n", fmdev->irq_info.flag); in fm_irq_handle_flag_getcmd_resp()
598 if (fmdev->irq_info.flag & FM_MAL_EVENT & fmdev->irq_info.mask) in fm_irq_handle_hw_malfunction()
599 fmerr("irq: HW MAL int received - do nothing\n"); in fm_irq_handle_hw_malfunction()
607 if (fmdev->irq_info.flag & FM_RDS_EVENT & fmdev->irq_info.mask) { in fm_irq_handle_rds_start()
609 fmdev->irq_info.stage = FM_RDS_SEND_RDS_GETCMD_IDX; in fm_irq_handle_rds_start()
612 fmdev->irq_info.stage = FM_HW_TUNE_OP_ENDED_IDX; in fm_irq_handle_rds_start()
629 struct tuned_station_info *stat_info = &fmdev->rx.stat_info; in fm_rx_update_af_cache()
630 u8 reg_idx = fmdev->rx.region.fm_band; in fm_rx_update_af_cache()
632 u32 freq; in fm_rx_update_af_cache() local
636 fmdev->rx.stat_info.af_list_max = (af - FM_RDS_1_AF_FOLLOWS + 1); in fm_rx_update_af_cache()
637 fmdev->rx.stat_info.afcache_size = 0; in fm_rx_update_af_cache()
638 fmdbg("No of expected AF : %d\n", fmdev->rx.stat_info.af_list_max); in fm_rx_update_af_cache()
649 freq = fmdev->rx.region.bot_freq + (af * 100); in fm_rx_update_af_cache()
650 if (freq == fmdev->rx.freq) { in fm_rx_update_af_cache()
651 fmdbg("Current freq(%d) is matching with received AF(%d)\n", in fm_rx_update_af_cache()
652 fmdev->rx.freq, freq); in fm_rx_update_af_cache()
656 for (index = 0; index < stat_info->afcache_size; index++) { in fm_rx_update_af_cache()
657 if (stat_info->af_cache[index] == freq) in fm_rx_update_af_cache()
660 /* Reached the limit of the list - ignore the next AF */ in fm_rx_update_af_cache()
661 if (index == stat_info->af_list_max) { in fm_rx_update_af_cache()
667 * in the list - add it. in fm_rx_update_af_cache()
669 if (index == stat_info->afcache_size) { in fm_rx_update_af_cache()
670 fmdbg("Storing AF %d to cache index %d\n", freq, index); in fm_rx_update_af_cache()
671 stat_info->af_cache[index] = freq; in fm_rx_update_af_cache()
672 stat_info->afcache_size++; in fm_rx_update_af_cache()
691 if (fmdev->asci_id != 0x6350) { in fm_rdsparse_swapbytes()
692 rds_buff = &rds_format->data.groupdatabuff.buff[0]; in fm_rdsparse_swapbytes()
704 struct fm_rds *rds = &fmdev->rx.rds; in fm_irq_handle_rdsdata_getcmd_resp()
716 rds_data = skb->data; in fm_irq_handle_rdsdata_getcmd_resp()
717 rds_len = skb->len; in fm_irq_handle_rdsdata_getcmd_resp()
726 blk_idx = (type <= FM_RDS_BLOCK_C ? type : (type - 1)); in fm_irq_handle_rdsdata_getcmd_resp()
735 rds->last_blk_idx = -1; in fm_irq_handle_rdsdata_getcmd_resp()
740 idx = array_index_nospec(blk_idx * (FM_RDS_BLK_SIZE - 1), in fm_irq_handle_rdsdata_getcmd_resp()
741 FM_RX_RDS_INFO_FIELD_MAX - (FM_RDS_BLK_SIZE - 1)); in fm_irq_handle_rdsdata_getcmd_resp()
744 FM_RDS_BLK_SIZE - 1); in fm_irq_handle_rdsdata_getcmd_resp()
746 rds->last_blk_idx = blk_idx; in fm_irq_handle_rdsdata_getcmd_resp()
758 if (fmdev->rx.stat_info.picode != cur_picode) in fm_irq_handle_rdsdata_getcmd_resp()
759 fmdev->rx.stat_info.picode = cur_picode; in fm_irq_handle_rdsdata_getcmd_resp()
773 rds_len -= FM_RDS_BLK_SIZE; in fm_irq_handle_rdsdata_getcmd_resp()
778 rds_data = skb->data; in fm_irq_handle_rdsdata_getcmd_resp()
779 rds_len = skb->len; in fm_irq_handle_rdsdata_getcmd_resp()
781 spin_lock_irqsave(&fmdev->rds_buff_lock, flags); in fm_irq_handle_rdsdata_getcmd_resp()
788 blk_idx = (type <= FM_RDS_BLOCK_C ? type : (type - 1)); in fm_irq_handle_rdsdata_getcmd_resp()
796 memcpy(&rds->buff[rds->wr_idx], &tmpbuf, FM_RDS_BLK_SIZE); in fm_irq_handle_rdsdata_getcmd_resp()
797 rds->wr_idx = (rds->wr_idx + FM_RDS_BLK_SIZE) % rds->buf_size; in fm_irq_handle_rdsdata_getcmd_resp()
800 if (rds->wr_idx == rds->rd_idx) { in fm_irq_handle_rdsdata_getcmd_resp()
802 rds->wr_idx = 0; in fm_irq_handle_rdsdata_getcmd_resp()
803 rds->rd_idx = 0; in fm_irq_handle_rdsdata_getcmd_resp()
806 rds_len -= FM_RDS_BLK_SIZE; in fm_irq_handle_rdsdata_getcmd_resp()
809 spin_unlock_irqrestore(&fmdev->rds_buff_lock, flags); in fm_irq_handle_rdsdata_getcmd_resp()
812 if (rds->wr_idx != rds->rd_idx) in fm_irq_handle_rdsdata_getcmd_resp()
813 wake_up_interruptible(&rds->read_queue); in fm_irq_handle_rdsdata_getcmd_resp()
825 if (fmdev->irq_info.flag & (FM_FR_EVENT | FM_BL_EVENT) & fmdev-> in fm_irq_handle_tune_op_ended()
828 if (test_and_clear_bit(FM_AF_SWITCH_INPROGRESS, &fmdev->flag)) { in fm_irq_handle_tune_op_ended()
829 fmdev->irq_info.stage = FM_AF_JUMP_RD_FREQ_IDX; in fm_irq_handle_tune_op_ended()
831 complete(&fmdev->maintask_comp); in fm_irq_handle_tune_op_ended()
832 fmdev->irq_info.stage = FM_HW_POWER_ENB_IDX; in fm_irq_handle_tune_op_ended()
835 fmdev->irq_info.stage = FM_HW_POWER_ENB_IDX; in fm_irq_handle_tune_op_ended()
842 if (fmdev->irq_info.flag & FM_POW_ENB_EVENT) { in fm_irq_handle_power_enb()
844 complete(&fmdev->maintask_comp); in fm_irq_handle_power_enb()
852 if ((fmdev->rx.af_mode == FM_RX_RDS_AF_SWITCH_MODE_ON) && in fm_irq_handle_low_rssi_start()
853 (fmdev->irq_info.flag & FM_LEV_EVENT & fmdev->irq_info.mask) && in fm_irq_handle_low_rssi_start()
854 (fmdev->rx.freq != FM_UNDEFINED_FREQ) && in fm_irq_handle_low_rssi_start()
855 (fmdev->rx.stat_info.afcache_size != 0)) { in fm_irq_handle_low_rssi_start()
859 fmdev->irq_info.mask &= ~FM_LEV_EVENT; in fm_irq_handle_low_rssi_start()
861 fmdev->rx.afjump_idx = 0; in fm_irq_handle_low_rssi_start()
862 fmdev->rx.freq_before_jump = fmdev->rx.freq; in fm_irq_handle_low_rssi_start()
863 fmdev->irq_info.stage = FM_AF_JUMP_SETPI_IDX; in fm_irq_handle_low_rssi_start()
866 fmdev->irq_info.stage = FM_SEND_INTMSK_CMD_IDX; in fm_irq_handle_low_rssi_start()
876 /* Set PI code - must be updated if the AF list is not empty */ in fm_irq_afjump_set_pi()
877 payload = fmdev->rx.stat_info.picode; in fm_irq_afjump_set_pi()
911 fmdbg("Switch to %d KHz\n", fmdev->rx.stat_info.af_cache[fmdev->rx.afjump_idx]); in fm_irq_afjump_setfreq()
912 frq_index = (fmdev->rx.stat_info.af_cache[fmdev->rx.afjump_idx] - in fm_irq_afjump_setfreq()
913 fmdev->rx.region.bot_freq) / FM_FREQ_MUL; in fm_irq_afjump_setfreq()
957 fmdev->irq_info.stage = FM_SEND_FLAG_GETCMD_IDX; in fm_irq_handle_start_afjump_resp()
958 set_bit(FM_AF_SWITCH_INPROGRESS, &fmdev->flag); in fm_irq_handle_start_afjump_resp()
959 clear_bit(FM_INTTASK_RUNNING, &fmdev->flag); in fm_irq_handle_start_afjump_resp()
981 memcpy(&read_freq, skb->data, sizeof(read_freq)); in fm_irq_afjump_rd_freq_resp()
983 curr_freq = fmdev->rx.region.bot_freq + ((u32)read_freq * FM_FREQ_MUL); in fm_irq_afjump_rd_freq_resp()
985 jumped_freq = fmdev->rx.stat_info.af_cache[fmdev->rx.afjump_idx]; in fm_irq_afjump_rd_freq_resp()
988 if ((curr_freq != fmdev->rx.freq_before_jump) && (curr_freq == jumped_freq)) { in fm_irq_afjump_rd_freq_resp()
989 fmdbg("Successfully switched to alternate freq %d\n", curr_freq); in fm_irq_afjump_rd_freq_resp()
990 fmdev->rx.freq = curr_freq; in fm_irq_afjump_rd_freq_resp()
994 if (fmdev->rx.af_mode == FM_RX_RDS_AF_SWITCH_MODE_ON) in fm_irq_afjump_rd_freq_resp()
995 fmdev->irq_info.mask |= FM_LEV_EVENT; in fm_irq_afjump_rd_freq_resp()
997 fmdev->irq_info.stage = FM_LOW_RSSI_FINISH_IDX; in fm_irq_afjump_rd_freq_resp()
998 } else { /* jump to the next freq in the AF list */ in fm_irq_afjump_rd_freq_resp()
999 fmdev->rx.afjump_idx++; in fm_irq_afjump_rd_freq_resp()
1001 /* If we reached the end of the list - stop searching */ in fm_irq_afjump_rd_freq_resp()
1002 if (fmdev->rx.afjump_idx >= fmdev->rx.stat_info.afcache_size) { in fm_irq_afjump_rd_freq_resp()
1004 fmdev->irq_info.stage = FM_LOW_RSSI_FINISH_IDX; in fm_irq_afjump_rd_freq_resp()
1005 } else { /* AF List is not over - try next one */ in fm_irq_afjump_rd_freq_resp()
1007 fmdbg("Trying next freq in AF cache\n"); in fm_irq_afjump_rd_freq_resp()
1008 fmdev->irq_info.stage = FM_AF_JUMP_SETPI_IDX; in fm_irq_afjump_rd_freq_resp()
1023 /* Re-enable FM interrupts */ in fm_irq_send_intmsk_cmd()
1024 payload = fmdev->irq_info.mask; in fm_irq_send_intmsk_cmd()
1041 fmdev->irq_info.stage = FM_SEND_FLAG_GETCMD_IDX; in fm_irq_handle_intmsk_cmd_resp()
1044 if (test_and_clear_bit(FM_INTTASK_SCHEDULE_PENDING, &fmdev->flag)) in fm_irq_handle_intmsk_cmd_resp()
1045 fmdev->irq_info.handlers[fmdev->irq_info.stage](fmdev); in fm_irq_handle_intmsk_cmd_resp()
1047 clear_bit(FM_INTTASK_RUNNING, &fmdev->flag); in fm_irq_handle_intmsk_cmd_resp()
1054 poll_wait(file, &fmdev->rx.rds.read_queue, pts); in fmc_is_rds_data_available()
1055 if (fmdev->rx.rds.rd_idx != fmdev->rx.rds.wr_idx) in fmc_is_rds_data_available()
1058 return -EAGAIN; in fmc_is_rds_data_available()
1070 if (fmdev->rx.rds.wr_idx == fmdev->rx.rds.rd_idx) { in fmc_transfer_rds_from_internal_buff()
1071 if (file->f_flags & O_NONBLOCK) in fmc_transfer_rds_from_internal_buff()
1072 return -EWOULDBLOCK; in fmc_transfer_rds_from_internal_buff()
1074 ret = wait_event_interruptible(fmdev->rx.rds.read_queue, in fmc_transfer_rds_from_internal_buff()
1075 (fmdev->rx.rds.wr_idx != fmdev->rx.rds.rd_idx)); in fmc_transfer_rds_from_internal_buff()
1077 return -EINTR; in fmc_transfer_rds_from_internal_buff()
1086 spin_lock_irqsave(&fmdev->rds_buff_lock, flags); in fmc_transfer_rds_from_internal_buff()
1088 if (fmdev->rx.rds.wr_idx == fmdev->rx.rds.rd_idx) { in fmc_transfer_rds_from_internal_buff()
1089 spin_unlock_irqrestore(&fmdev->rds_buff_lock, flags); in fmc_transfer_rds_from_internal_buff()
1092 memcpy(tmpbuf, &fmdev->rx.rds.buff[fmdev->rx.rds.rd_idx], in fmc_transfer_rds_from_internal_buff()
1094 fmdev->rx.rds.rd_idx += FM_RDS_BLK_SIZE; in fmc_transfer_rds_from_internal_buff()
1095 if (fmdev->rx.rds.rd_idx >= fmdev->rx.rds.buf_size) in fmc_transfer_rds_from_internal_buff()
1096 fmdev->rx.rds.rd_idx = 0; in fmc_transfer_rds_from_internal_buff()
1098 spin_unlock_irqrestore(&fmdev->rds_buff_lock, flags); in fmc_transfer_rds_from_internal_buff()
1112 switch (fmdev->curr_fmmode) { in fmc_set_freq()
1120 return -EINVAL; in fmc_set_freq()
1126 if (fmdev->rx.freq == FM_UNDEFINED_FREQ) { in fmc_get_freq()
1128 return -EPERM; in fmc_get_freq()
1132 return -ENOMEM; in fmc_get_freq()
1135 switch (fmdev->curr_fmmode) { in fmc_get_freq()
1137 *cur_tuned_frq = fmdev->rx.freq; in fmc_get_freq()
1145 return -EINVAL; in fmc_get_freq()
1152 switch (fmdev->curr_fmmode) { in fmc_set_region()
1160 return -EINVAL; in fmc_set_region()
1166 switch (fmdev->curr_fmmode) { in fmc_set_mute_mode()
1174 return -EINVAL; in fmc_set_mute_mode()
1180 switch (fmdev->curr_fmmode) { in fmc_set_stereo_mono()
1188 return -EINVAL; in fmc_set_stereo_mono()
1194 switch (fmdev->curr_fmmode) { in fmc_set_rds_mode()
1202 return -EINVAL; in fmc_set_rds_mode()
1212 if (!test_bit(FM_CORE_READY, &fmdev->flag)) { in fm_power_down()
1214 return -EPERM; in fm_power_down()
1216 if (fmdev->curr_fmmode == FM_MODE_OFF) { in fm_power_down()
1240 set_bit(FM_FW_DW_INPROGRESS, &fmdev->flag); in fm_download_firmware()
1243 &fmdev->radio_dev->dev); in fm_download_firmware()
1248 fmdbg("Firmware(%s) length : %zu bytes\n", fw_name, fw_entry->size); in fm_download_firmware()
1250 fw_data = (void *)fw_entry->data; in fm_download_firmware()
1251 fw_len = fw_entry->size; in fm_download_firmware()
1254 if (fw_header->magic != FM_FW_FILE_HEADER_MAGIC) { in fm_download_firmware()
1256 ret = -EINVAL; in fm_download_firmware()
1259 fmdbg("FW(%s) magic number : 0x%x\n", fw_name, fw_header->magic); in fm_download_firmware()
1263 fw_len -= sizeof(struct bts_header); in fm_download_firmware()
1268 switch (action->type) { in fm_download_firmware()
1270 ret = fmc_send_cmd(fmdev, 0, 0, action->data, in fm_download_firmware()
1271 action->size, NULL, NULL); in fm_download_firmware()
1278 delay = (struct bts_action_delay *)action->data; in fm_download_firmware()
1279 mdelay(delay->msec); in fm_download_firmware()
1283 fw_data += (sizeof(struct bts_action) + (action->size)); in fm_download_firmware()
1284 fw_len -= (sizeof(struct bts_action) + (action->size)); in fm_download_firmware()
1287 fw_entry->size - fw_len, fw_entry->size); in fm_download_firmware()
1290 clear_bit(FM_FW_DW_INPROGRESS, &fmdev->flag); in fm_download_firmware()
1317 return -EINVAL; in fm_power_up()
1335 /* Allow the chip to settle down in Channel-8 mode */ in fm_power_up()
1371 /* Set FM Modes(TX, RX, OFF) */
1378 return -EINVAL; in fmc_set_mode()
1380 if (fmdev->curr_fmmode == fm_mode) { in fmc_set_mode()
1394 case FM_MODE_TX: /* TX Mode */ in fmc_set_mode()
1396 /* Power down before switching to TX or RX mode */ in fmc_set_mode()
1397 if (fmdev->curr_fmmode != FM_MODE_OFF) { in fmc_set_mode()
1411 fmdev->curr_fmmode = fm_mode; in fmc_set_mode()
1414 if (fmdev->curr_fmmode == FM_MODE_RX) { in fmc_set_mode()
1424 /* Returns current FM mode (TX, RX, OFF) */
1427 if (!test_bit(FM_CORE_READY, &fmdev->flag)) { in fmc_get_mode()
1429 return -EPERM; in fmc_get_mode()
1433 return -ENOMEM; in fmc_get_mode()
1436 *fmmode = fmdev->curr_fmmode; in fmc_get_mode()
1449 return -EFAULT; in fm_st_receive()
1452 if (skb->cb[0] != FM_PKT_LOGICAL_CHAN_NUMBER) { in fm_st_receive()
1454 return -EINVAL; in fm_st_receive()
1457 memcpy(skb_push(skb, 1), &skb->cb[0], 1); in fm_st_receive()
1458 skb_queue_tail(&fmdev->rx_q, skb); in fm_st_receive()
1459 tasklet_schedule(&fmdev->rx_task); in fm_st_receive()
1473 fmdev->streg_cbdata = data; in fm_st_reg_comp_cb()
1486 if (test_bit(FM_CORE_READY, &fmdev->flag)) { in fmc_prepare()
1505 if (ret == -EINPROGRESS) { in fmc_prepare()
1507 fmdev->streg_cbdata = -EINPROGRESS; in fmc_prepare()
1514 return -ETIMEDOUT; in fmc_prepare()
1516 if (fmdev->streg_cbdata != 0) { in fmc_prepare()
1518 fmdev->streg_cbdata); in fmc_prepare()
1519 return -EAGAIN; in fmc_prepare()
1525 return -EAGAIN; in fmc_prepare()
1535 return -EAGAIN; in fmc_prepare()
1538 spin_lock_init(&fmdev->rds_buff_lock); in fmc_prepare()
1539 spin_lock_init(&fmdev->resp_skb_lock); in fmc_prepare()
1541 /* Initialize TX queue and TX tasklet */ in fmc_prepare()
1542 skb_queue_head_init(&fmdev->tx_q); in fmc_prepare()
1543 tasklet_setup(&fmdev->tx_task, send_tasklet); in fmc_prepare()
1546 skb_queue_head_init(&fmdev->rx_q); in fmc_prepare()
1547 tasklet_setup(&fmdev->rx_task, recv_tasklet); in fmc_prepare()
1549 fmdev->irq_info.stage = 0; in fmc_prepare()
1550 atomic_set(&fmdev->tx_cnt, 1); in fmc_prepare()
1551 fmdev->resp_comp = NULL; in fmc_prepare()
1553 timer_setup(&fmdev->irq_info.timer, int_timeout_handler, 0); in fmc_prepare()
1555 fmdev->irq_info.mask = FM_MAL_EVENT; in fmc_prepare()
1558 fmdev->rx.region = region_configs[default_radio_region]; in fmc_prepare()
1560 fmdev->rx.mute_mode = FM_MUTE_OFF; in fmc_prepare()
1561 fmdev->rx.rf_depend_mute = FM_RX_RF_DEPENDENT_MUTE_OFF; in fmc_prepare()
1562 fmdev->rx.rds.flag = FM_RDS_DISABLE; in fmc_prepare()
1563 fmdev->rx.freq = FM_UNDEFINED_FREQ; in fmc_prepare()
1564 fmdev->rx.rds_mode = FM_RDS_SYSTEM_RDS; in fmc_prepare()
1565 fmdev->rx.af_mode = FM_RX_RDS_AF_SWITCH_MODE_OFF; in fmc_prepare()
1566 fmdev->irq_info.retry = 0; in fmc_prepare()
1569 init_waitqueue_head(&fmdev->rx.rds.read_queue); in fmc_prepare()
1572 set_bit(FM_CORE_READY, &fmdev->flag); in fmc_prepare()
1586 if (!test_bit(FM_CORE_READY, &fmdev->flag)) { in fmc_release()
1591 wake_up_interruptible(&fmdev->rx.rds.read_queue); in fmc_release()
1593 tasklet_kill(&fmdev->tx_task); in fmc_release()
1594 tasklet_kill(&fmdev->rx_task); in fmc_release()
1596 skb_queue_purge(&fmdev->tx_q); in fmc_release()
1597 skb_queue_purge(&fmdev->rx_q); in fmc_release()
1599 fmdev->resp_comp = NULL; in fmc_release()
1600 fmdev->rx.freq = 0; in fmc_release()
1608 fmerr("Failed to de-register FM from ST %d\n", ret); in fmc_release()
1612 clear_bit(FM_CORE_READY, &fmdev->flag); in fmc_release()
1623 int ret = -ENOMEM; in fm_drv_init()
1632 fmdev->rx.rds.buf_size = default_rds_buf * FM_RDS_BLK_SIZE; in fm_drv_init()
1633 fmdev->rx.rds.buff = kzalloc(fmdev->rx.rds.buf_size, GFP_KERNEL); in fm_drv_init()
1634 if (NULL == fmdev->rx.rds.buff) { in fm_drv_init()
1643 fmdev->irq_info.handlers = int_handler_table; in fm_drv_init()
1644 fmdev->curr_fmmode = FM_MODE_OFF; in fm_drv_init()
1645 fmdev->tx_data.pwr_lvl = FM_PWR_LVL_DEF; in fm_drv_init()
1646 fmdev->tx_data.preemph = FM_TX_PREEMPH_50US; in fm_drv_init()
1650 kfree(fmdev->rx.rds.buff); in fm_drv_init()
1664 kfree(fmdev->rx.rds.buff); in fm_drv_exit()
1672 /* ------------- Module Info ------------- */