static long fm_ops_ioctl(struct file *filp, fm_u32 cmd, unsigned long arg) { fm_s32 ret = 0; struct fm_platform *plat = container_of(filp->f_dentry->d_inode->i_cdev, struct fm_platform, cdev); struct fm *fm = container_of(plat, struct fm, platform); WCN_DBG(FM_NTC | MAIN, "%s---pid(%d)---cmd(0x%08x)---arg(0x%08x)\n", current->comm, current->pid, cmd, (fm_u32)arg); if (fm_sys_state_get(fm) != FM_SUBSYS_RST_OFF) { WCN_DBG(FM_ALT | MAIN, "FM subsys is resetting, retry later\n"); ret = -FM_ESRST; return ret; } switch (cmd) { case FM_IOCTL_POWERUP: { struct fm_tune_parm parm; WCN_DBG(FM_NTC | MAIN, "FM_IOCTL_POWERUP:0\n"); if (copy_from_user(&parm, (void*)arg, sizeof(struct fm_tune_parm))) { ret = -EFAULT; goto out; } ret = fm_powerup(fm, &parm); if (ret < 0) goto out; ret = fm_tune(fm, &parm); if (ret < 0) goto out; if (copy_to_user((void*)arg, &parm, sizeof(struct fm_tune_parm))) { ret = -EFAULT; goto out; } WCN_DBG(FM_NTC | MAIN, "FM_IOCTL_POWERUP:1\n"); break; } case FM_IOCTL_POWERDOWN: { WCN_DBG(FM_NTC | MAIN, "FM_IOCTL_POWERDOWN:0\n"); ret = fm_powerdown(fm); WCN_DBG(FM_NTC | MAIN, "FM_IOCTL_POWERDOWN:1\n"); break; } case FM_IOCTL_TUNE: { struct fm_tune_parm parm; WCN_DBG(FM_NTC | MAIN, "FM_IOCTL_TUNE:0\n"); if (copy_from_user(&parm, (void*)arg, sizeof(struct fm_tune_parm))) { ret = -EFAULT; goto out; } ret = fm_tune(fm, &parm); if (ret < 0) { goto out; } if (copy_to_user((void*)arg, &parm, sizeof(struct fm_tune_parm))) { ret = -EFAULT; goto out; } WCN_DBG(FM_NTC | MAIN, "FM_IOCTL_TUNE:1\n"); break; } case FM_IOCTL_SOFT_MUTE_TUNE: { struct fm_softmute_tune_t parm; fm_cqi_log();//cqi log tool WCN_DBG(FM_NTC | MAIN,"......FM_IOCTL_SOFT_MUTE_TUNE......\n"); if(copy_from_user(&parm, (void*)arg, sizeof(struct fm_softmute_tune_t))) { ret = -EFAULT; goto out; } ret = fm_soft_mute_tune(fm, &parm); if (ret < 0) { goto out; } if(copy_to_user((void*)arg, &parm, sizeof(struct fm_softmute_tune_t))) { ret = -EFAULT; goto out; } break; } case FM_IOCTL_SEEK: { struct fm_seek_parm parm; WCN_DBG(FM_NTC | MAIN, "FM_IOCTL_SEEK:0\n"); if (copy_from_user(&parm, (void*)arg, sizeof(struct fm_seek_parm))) { ret = -EFAULT; goto out; } ret = fm_seek(fm, &parm); if (ret < 0) { goto out; } if (copy_to_user((void*)arg, &parm, sizeof(struct fm_seek_parm))) { ret = -EFAULT; goto out; } WCN_DBG(FM_NTC | MAIN, "FM_IOCTL_SEEK:1\n"); break; } case FM_IOCTL_SCAN: { struct fm_scan_parm parm; WCN_DBG(FM_NTC | MAIN, "FM_IOCTL_SCAN start\n"); if (copy_from_user(&parm, (void*)arg, sizeof(struct fm_scan_parm))) { WCN_DBG(FM_ALT | MAIN, "copy_from_user failed\n"); ret = -EFAULT; goto out; } ret = fm_scan(fm, &parm); if (ret < 0) goto out; if (copy_to_user((void*)arg, &parm, sizeof(struct fm_scan_parm))) { ret = -EFAULT; goto out; } WCN_DBG(FM_NTC | MAIN, "FM_IOCTL_SCAN end\n"); break; } case FM_IOCTL_TUNE_NEW: { struct fm_tune_t tune_tmp; WCN_DBG(FM_NTC | MAIN, "FM_IOCTL_TUNE_NEW\n"); if (copy_from_user(&tune_tmp, (void*)arg, sizeof(struct fm_tune_t))) { WCN_DBG(FM_ERR | MAIN, "tune new copy_from_user error\n"); ret = -EFAULT; goto out; } ret = fm_tune_new(fm, &tune_tmp); if (ret < 0) { goto out; } if (copy_to_user((void*)arg, &tune_tmp, sizeof(struct fm_tune_t))) { WCN_DBG(FM_ERR | MAIN, "tune new copy_to_user error\n"); ret = -EFAULT; goto out; } break; } case FM_IOCTL_SEEK_NEW: { struct fm_seek_t seek_tmp; WCN_DBG(FM_NTC | MAIN, "FM_IOCTL_SEEK_NEW\n"); if (copy_from_user(&seek_tmp, (void*)arg, sizeof(struct fm_seek_t))) { WCN_DBG(FM_ERR | MAIN, "seek new copy_from_user error\n"); ret = -EFAULT; goto out; } ret = fm_seek_new(fm, &seek_tmp); if (ret < 0) { goto out; } if (copy_to_user((void*)arg, &seek_tmp, sizeof(struct fm_seek_t))) { WCN_DBG(FM_ERR | MAIN, "seek new copy_to_user error\n"); ret = -EFAULT; goto out; } break; } case FM_IOCTL_SCAN_NEW: { struct fm_scan_t tmp; WCN_DBG(FM_NTC | MAIN, "FM_IOCTL_SCAN_NEW\n"); if (copy_from_user(&tmp, (void*)arg, sizeof(struct fm_scan_t))) { WCN_DBG(FM_ERR | MAIN, "copy_from_user error\n"); ret = -EFAULT; goto out; } switch (tmp.cmd) { case FM_SCAN_CMD_START: if ((tmp.upper > 10800) || (tmp.lower < 7600) || (tmp.space < 5) || (tmp.space > 20)) { WCN_DBG(FM_ERR | MAIN, "scan para error\n"); ret = -EFAULT; goto out; } parm.cmd = tmp.cmd; parm.lower = tmp.lower; parm.upper = tmp.upper; parm.space = tmp.space; ret = fm_scan_new(fm, &parm); if (ret < 0) { goto out; } break; case FM_SCAN_CMD_GET_CH_RSSI: if (parm.sr_size && parm.sr.ch_rssi_buf) { if (copy_to_user(tmp.sr.ch_rssi_buf, parm.sr.ch_rssi_buf, parm.num * sizeof(struct fm_ch_rssi))) { WCN_DBG(FM_ERR | MAIN, "scan copy_to_user err\n"); ret = -EFAULT; goto out; } } break; default: break; } tmp.num = parm.num; if (copy_to_user((void*)arg, &tmp, sizeof(struct fm_scan_t))) { WCN_DBG(FM_ERR | MAIN, "copy_to_user error\n"); ret = -EFAULT; goto out; } break; } case FM_IOCTL_CQI_GET: { struct fm_cqi_req cqi_req; fm_s8 *buf = NULL; fm_s32 tmp; WCN_DBG(FM_DBG | MAIN, "FM_IOCTL_CQI_GET\n"); if (copy_from_user(&cqi_req, (void*)arg, sizeof(struct fm_cqi_req))) { WCN_DBG(FM_ALT | MAIN, "copy_from_user failed\n"); ret = -EFAULT; goto out; } if ((cqi_req.ch_num*sizeof(struct fm_cqi) > cqi_req.buf_size) || !cqi_req.cqi_buf) { ret = -FM_EPARA; goto out; } tmp = cqi_req.ch_num / 16 + ((cqi_req.ch_num % 16) ? 1 : 0); tmp = tmp * 16 * sizeof(struct fm_cqi); buf = fm_zalloc(tmp); if (!buf) { ret = -FM_ENOMEM; goto out; } ret = fm_cqi_get(fm, cqi_req.ch_num, buf, tmp); if (ret) { fm_free(buf); WCN_DBG(FM_ALT | MAIN, "get cqi failed\n"); goto out; } if (copy_to_user((void*)cqi_req.cqi_buf, buf, cqi_req.ch_num*sizeof(struct fm_cqi))) { fm_free(buf); ret = -EFAULT; goto out; } fm_free(buf); break; } case FM_IOCTL_GET_HW_INFO: { struct fm_hw_info info; WCN_DBG(FM_NTC | MAIN, "FM_IOCTL_GET_HW_INFO\n"); ret = fm_get_hw_info(fm, &info); if (ret) { WCN_DBG(FM_ALT | MAIN, "get hw info failed\n"); goto out; } if (copy_to_user((void*)arg, &info, sizeof(struct fm_hw_info))) { ret = -EFAULT; goto out; } break; } case FM_IOCTL_GET_I2S_INFO: { struct fm_i2s_info i2sinfo; WCN_DBG(FM_NTC | MAIN, "FM_IOCTL_GET_I2S_INFO\n"); ret = fm_get_i2s_info(fm, &i2sinfo); if (ret) { WCN_DBG(FM_ALT | MAIN, "get i2s info failed\n"); goto out; } if (copy_to_user((void*)arg, &i2sinfo, sizeof(struct fm_i2s_info))) { ret = -EFAULT; goto out; } break; } case FM_IOCTL_SETVOL: { fm_u32 vol; WCN_DBG(FM_NTC | MAIN, "FM_IOCTL_SETVOL start\n"); if (copy_from_user(&vol, (void*)arg, sizeof(fm_u32))) { WCN_DBG(FM_ALT | MAIN, "copy_from_user failed\n"); ret = -EFAULT; goto out; } ret = fm_setvol(fm, vol); WCN_DBG(FM_NTC | MAIN, "FM_IOCTL_SETVOL end:%d\n", vol); break; } case FM_IOCTL_GETVOL: { fm_u32 vol; WCN_DBG(FM_NTC | MAIN, "FM_IOCTL_GETVOL start\n"); ret = fm_getvol(fm, &vol); if (ret < 0) goto out; if (copy_to_user((void*)arg, &vol, sizeof(fm_u32))) { ret = -EFAULT; goto out; } WCN_DBG(FM_NTC | MAIN, "FM_IOCTL_GETVOL end=%d\n",vol); break; } case FM_IOCTL_MUTE: { fm_u32 bmute; WCN_DBG(FM_NTC| MAIN, "FM_IOCTL_MUTE start\n"); if (copy_from_user(&bmute, (void*)arg, sizeof(fm_u32))) { ret = -EFAULT; goto out; } ret = fm_mute(fm, bmute); WCN_DBG(FM_NTC| MAIN, "FM_IOCTL_MUTE end-%d\n", bmute); break; } case FM_IOCTL_GETRSSI: { fm_s32 rssi = 0; ret = fm_getrssi(fm, &rssi); if (ret < 0) goto out; if (copy_to_user((void*)arg, &rssi, sizeof(fm_s32))) { ret = -EFAULT; goto out; } WCN_DBG(FM_NTC | MAIN, "FM_IOCTL_GETRSSI:%d\n",rssi); break; } case FM_IOCTL_RW_REG: { struct fm_ctl_parm parm_ctl; WCN_DBG(FM_DBG | MAIN, "FM_IOCTL_RW_REG\n"); if (copy_from_user(&parm_ctl, (void*)arg, sizeof(struct fm_ctl_parm))) { ret = -EFAULT; goto out; } if (parm_ctl.rw_flag == 0) { ret = fm_reg_write(fm, parm_ctl.addr, parm_ctl.val); } else { ret = fm_reg_read(fm, parm_ctl.addr, &parm_ctl.val); } if (ret < 0) goto out; if ((parm_ctl.rw_flag == 0x01) && (!ret)) { if (copy_to_user((void*)arg, &parm_ctl, sizeof(struct fm_ctl_parm))) { ret = -EFAULT; goto out; } } break; } case FM_IOCTL_GETCHIPID: { fm_u16 chipid; ret = fm_chipid_get(fm, &chipid); WCN_DBG(FM_DBG | MAIN, "FM_IOCTL_GETCHIPID:%04x\n", chipid); if (ret < 0) goto out; if (copy_to_user((void*)arg, &chipid, sizeof(fm_u16))) { ret = -EFAULT; goto out; } break; } case FM_IOCTL_GETMONOSTERO: { fm_u16 usStereoMono; ret = fm_monostereo_get(fm, &usStereoMono); WCN_DBG(FM_DBG | MAIN, "FM_IOCTL_GETMONOSTERO:%04x\n", usStereoMono); if (ret < 0) goto out; if (copy_to_user((void*)arg, &usStereoMono, sizeof(fm_u16))) { ret = -EFAULT; goto out; } break; } case FM_IOCTL_SETMONOSTERO: { WCN_DBG(FM_DBG | MAIN, "FM_IOCTL_SETMONOSTERO, %d\n", (fm_s32)arg); ret = fm_monostereo_set(fm, (fm_s32)arg); break; } case FM_IOCTL_GETCURPAMD: { fm_u16 PamdLevl; ret = fm_pamd_get(fm, &PamdLevl); WCN_DBG(FM_DBG | MAIN, "FM_IOCTL_GETCURPAMD:%d\n", PamdLevl); if (ret < 0) goto out; if (copy_to_user((void*)arg, &PamdLevl, sizeof(fm_u16))) ret = -EFAULT; goto out; break; } case FM_IOCTL_GETCAPARRAY: { fm_s32 ca; ret = fm_caparray_get(fm, &ca); WCN_DBG(FM_DBG | MAIN, "FM_IOCTL_GETCAPARRAY:%d\n", ca); if (ret < 0) goto out; if (copy_to_user((void*)arg, &ca, sizeof(fm_s32))) { ret = -EFAULT; goto out; } break; } case FM_IOCTL_EM_TEST: { struct fm_em_parm parm_em; WCN_DBG(FM_DBG | MAIN, "FM_IOCTL_EM_TEST\n"); if (copy_from_user(&parm_em, (void*)arg, sizeof(struct fm_em_parm))) { ret = -EFAULT; goto out; } ret = fm_em_test(fm, parm_em.group_idx, parm_em.item_idx, parm_em.item_value); break; } case FM_IOCTL_RDS_SUPPORT: { fm_s32 support = FM_RDS_ENABLE; WCN_DBG(FM_NTC | MAIN, "FM_IOCTL_RDS_SUPPORT\n"); if (copy_to_user((void*)arg, &support, sizeof(fm_s32))) { ret = -EFAULT; goto out; } break; } case FM_IOCTL_IS_FM_POWERED_UP: { fm_u32 powerup; WCN_DBG(FM_DBG | MAIN, "FM_IOCTL_IS_FM_POWERED_UP"); if (fm->chipon && fm_pwr_state_get(fm)) { powerup = 1; } else { powerup = 0; } if (copy_to_user((void*)arg, &powerup, sizeof(fm_u32))) { ret = -EFAULT; goto out; } break; } case FM_IOCTL_RDS_ONOFF: { fm_u16 rdson_off = 0; WCN_DBG(FM_NTC | MAIN, "FM_IOCTL_RDS_ONOFF start\n"); if (copy_from_user(&rdson_off, (void*)arg, sizeof(fm_u16))) { ret = -EFAULT; goto out; } ret = fm_rds_onoff(fm, rdson_off); WCN_DBG(FM_NTC | MAIN, "FM_IOCTL_RDS_ONOFF end:%d\n",rdson_off); break; } case FM_IOCTL_GETGOODBCNT: { fm_u16 uGBLCNT = 0; ret = fm_rds_good_bc_get(fm, &uGBLCNT); WCN_DBG(FM_DBG | MAIN, "FM_IOCTL_GETGOODBCNT:%d\n", uGBLCNT); if (ret < 0) goto out; if (copy_to_user((void*)arg, &uGBLCNT, sizeof(fm_u16))) { ret = -EFAULT; goto out; } break; } case FM_IOCTL_GETBADBNT: { fm_u16 uBadBLCNT = 0; ret = fm_rds_bad_bc_get(fm, &uBadBLCNT); WCN_DBG(FM_DBG | MAIN, "FM_IOCTL_GETBADBNT:%d\n", uBadBLCNT); if (ret < 0) goto out; if (copy_to_user((void*)arg, &uBadBLCNT, sizeof(fm_u16))) { ret = -EFAULT; goto out; } break; } case FM_IOCTL_GETBLERRATIO: { fm_u16 uBlerRatio = 0; ret = fm_rds_bler_ratio_get(fm, &uBlerRatio); WCN_DBG(FM_DBG | MAIN, "FM_IOCTL_GETBLERRATIO:%d\n", uBlerRatio); if (ret < 0) goto out; if (copy_to_user((void*)arg, &uBlerRatio, sizeof(fm_u16))) { ret = -EFAULT; goto out; } break; } case FM_IOCTL_ANA_SWITCH: { fm_s32 antenna = -1; WCN_DBG(FM_DBG | MAIN, "FM_IOCTL_ANA_SWITCH\n"); if (copy_from_user(&antenna, (void*)arg, sizeof(fm_s32))) { WCN_DBG(FM_ALT | MAIN, "copy from user error\n"); ret = -EFAULT; goto out; } ret = fm_ana_switch(fm, antenna); break; } case FM_IOCTL_RDS_GROUPCNT: { struct rds_group_cnt_req_t gc_req; WCN_DBG(FM_DBG | MAIN, "......FM_IOCTL_RDS_GROUPCNT......\n"); if (copy_from_user(&gc_req, (void*)arg, sizeof(struct rds_group_cnt_req_t))) { WCN_DBG(FM_ALT | MAIN, "copy_from_user error\n"); ret = -EFAULT; goto out; } //handle group counter request switch (gc_req.op) { case RDS_GROUP_CNT_READ: ret = fm_rds_group_cnt_get(fm, &gc_req.gc); break; case RDS_GROUP_CNT_WRITE: break; case RDS_GROUP_CNT_RESET: ret = fm_rds_group_cnt_reset(fm); break; default: break; } if (copy_to_user((void*)arg, &gc_req, sizeof(struct rds_group_cnt_req_t))) { WCN_DBG(FM_ALT | MAIN, "copy_to_user error\n"); ret = -EFAULT; goto out; } break; } case FM_IOCTL_RDS_GET_LOG: { struct rds_raw_t rds_log; fm_s32 len; WCN_DBG(FM_DBG | MAIN, "......FM_IOCTL_RDS_GET_LOG......\n"); //fetch a record form RDS log buffer ret = fm_rds_log_get(fm, (struct rds_rx_t*) & (rds_log.data), &len); rds_log.dirty = TRUE; rds_log.len = (len < sizeof(rds_log.data)) ? len : sizeof(rds_log.data); if (ret < 0) goto out; if (copy_to_user((void*)arg, &rds_log, rds_log.len + 2*sizeof(fm_s32))) { WCN_DBG(FM_ALT | MAIN, "copy_to_user error\n"); ret = -EFAULT; goto out; } break; } case FM_IOCTL_RDS_BC_RST: { WCN_DBG(FM_DBG | MAIN, "FM_IOCTL_RDS_BC_RST\n"); ret = fm_rds_block_cnt_reset(fm); break; } case FM_IOCTL_I2S_SETTING: { struct fm_i2s_setting i2s_cfg; WCN_DBG(FM_DBG | MAIN, "FM_IOCTL_I2S_SETTING\n"); if (copy_from_user(&i2s_cfg, (void*)arg, sizeof(struct fm_i2s_setting))) { WCN_DBG(FM_ALT | MAIN, "i2s set, copy_from_user err\n"); ret = -EFAULT; goto out; } ret = fm_i2s_set(fm, i2s_cfg.onoff, i2s_cfg.mode, i2s_cfg.sample); if (ret) { WCN_DBG(FM_ALT | MAIN, "Set i2s err\n"); goto out; } break; } case FM_IOCTL_IS_DESE_CHAN: { fm_s32 tmp; WCN_DBG(FM_DBG | MAIN, "FM_IOCTL_IS_DESE_CHAN\n"); if (copy_from_user(&tmp, (void*)arg, sizeof(fm_s32))) { WCN_DBG(FM_ALT | MAIN, "is dese chan, copy_from_user err\n"); ret = -EFAULT; goto out; } tmp = fm_is_dese_chan(fm, (fm_u16)tmp); if (copy_to_user((void*)arg, &tmp, sizeof(fm_s32))) { WCN_DBG(FM_ALT | MAIN, "is dese chan, copy_to_user err\n"); ret = -EFAULT; goto out; } break; } case FM_IOCTL_DESENSE_CHECK: { fm_desense_check_t tmp; WCN_DBG(FM_DBG | MAIN, "FM_IOCTL_IS_DESE_CHAN\n"); if (copy_from_user(&tmp, (void*)arg, sizeof(fm_desense_check_t))) { WCN_DBG(FM_ALT | MAIN, "desene check, copy_from_user err\n"); ret = -EFAULT; goto out; } ret = fm_desense_check(fm, (fm_u16)tmp.freq,tmp.rssi); /*if (copy_to_user((void*)arg, &tmp, sizeof(fm_desense_check_t))) { WCN_DBG(FM_ALT | MAIN, "desene check, copy_to_user err\n"); ret = -EFAULT; goto out; }*/ break; } case FM_IOCTL_SCAN_GETRSSI: { /*struct fm_rssi_req *req; WCN_DBG(FM_DBG | MAIN, "FM_IOCTL_SCAN_GETRSSI\n"); if(!(req = fm_vmalloc(sizeof(struct fm_rssi_req)))) { WCN_DBG(FM_ALT | MAIN, "fm_vmalloc err\n"); ret = -EFAULT; goto out; } if(copy_from_user(req, (void*)arg, sizeof(struct fm_rssi_req))) { WCN_DBG(FM_ALT | MAIN, "copy_from_user err\n"); ret = -EFAULT; fm_vfree(req); goto out; } ret = fm_get_rssi_after_scan(fm, req); if(-ERR_FW_NORES == ret){ WCN_DBG(FM_ALT | MAIN, "fm_get_rssi_after_scan err\n"); } if(copy_to_user((void*)arg, req, sizeof(struct fm_rssi_req))) { WCN_DBG(FM_ALT | MAIN, "copy_to_user err\n"); ret = -EFAULT; fm_vfree(req); goto out; } */ WCN_DBG(FM_ALT | MAIN, "FM_IOCTL_SCAN_GETRSSI:not support\n"); break; } case FM_IOCTL_DUMP_REG: { WCN_DBG(FM_NTC | MAIN,"......FM_IOCTL_DUMP_REG......\n"); ret = fm_dump_reg(); if(ret) { WCN_DBG(FM_ALT | MAIN, "fm_dump_reg err\n"); } break; } case FM_IOCTL_GPS_RTC_DRIFT:{ struct fm_gps_rtc_info rtc_info; WCN_DBG(FM_NTC | MAIN,"......FM_IOCTL_GPS_RTC_DRIFT......\n"); if (fm_false == fm->chipon){ WCN_DBG(FM_ERR | MAIN,"ERROR, FM chip is OFF\n"); ret = -EFAULT; goto out; } if(copy_from_user(&rtc_info, (void*)arg, sizeof(struct fm_gps_rtc_info))){ WCN_DBG(FM_ERR | MAIN,"copy_from_user error\n"); ret = -EFAULT; goto out; } ret = fm_get_gps_rtc_info(&rtc_info); if(ret){ WCN_DBG(FM_ERR | MAIN,"fm_get_gps_rtc_info error\n"); goto out; } break; } case FM_IOCTL_OVER_BT_ENABLE: { fm_s32 fm_via_bt = -1; WCN_DBG(FM_NTC | MAIN,"......FM_IOCTL_OVER_BT_ENABLE......\n"); if(copy_from_user(&fm_via_bt, (void*)arg, sizeof(int32_t))){ WCN_DBG(FM_ERR | MAIN,"copy_from_user error\n"); ret = -EFAULT; goto out; } ret = fm_over_bt(fm, fm_via_bt); if(ret) { WCN_DBG(FM_ERR | MAIN, "fm_over_bt err\n"); } break; } /***************************FM Tx function************************************/ case FM_IOCTL_TX_SUPPORT: { fm_s32 tx_support = -1; WCN_DBG(FM_NTC | MAIN,"......FM_IOCTL_TX_SUPPORT......\n"); ret = fm_tx_support(fm,&tx_support); if(ret) { WCN_DBG(FM_ERR | MAIN, "fm_tx_support err\n"); } if (copy_to_user((void*)arg, &tx_support, sizeof(fm_s32))) { WCN_DBG(FM_ERR | MAIN,"copy_to_user error\n"); ret = -EFAULT; goto out; } break; } case FM_IOCTL_POWERUP_TX: { struct fm_tune_parm parm; WCN_DBG(FM_NTC | MAIN, "FM_IOCTL_POWERUP_TX:0\n"); if (copy_from_user(&parm, (void*)arg, sizeof(struct fm_tune_parm))) { ret = -EFAULT; goto out; } ret = fm_powerup_tx(fm, &parm); if (ret < 0) { goto out; } ret = fm_tune_tx(fm, &parm); if (ret < 0) goto out; if (copy_to_user((void*)arg, &parm, sizeof(struct fm_tune_parm))) { ret = -EFAULT; goto out; } WCN_DBG(FM_NTC | MAIN, "FM_IOCTL_POWERUP_TX:1\n"); break; } case FM_IOCTL_TUNE_TX: { struct fm_tune_parm parm; WCN_DBG(FM_NTC | MAIN, "FM_IOCTL_TUNE_TX:0\n"); if (copy_from_user(&parm, (void*)arg, sizeof(struct fm_tune_parm))) { ret = -EFAULT; goto out; } ret = fm_tune_tx(fm, &parm); if (ret < 0) { goto out; } if (copy_to_user((void*)arg, &parm, sizeof(struct fm_tune_parm))) { ret = -EFAULT; goto out; } WCN_DBG(FM_NTC | MAIN, "FM_IOCTL_TUNE_TX:1\n"); break; } case FM_IOCTL_RDSTX_SUPPORT: { fm_s32 rds_tx_support = -1; WCN_DBG(FM_NTC | MAIN,"......FM_IOCTL_RDSTX_SUPPORT......\n"); ret = fm_rdstx_support(fm,&rds_tx_support); if(ret) { WCN_DBG(FM_ERR | MAIN, "fm_rdstx_support err\n"); } if (copy_to_user((void*)arg, &rds_tx_support, sizeof(fm_s32))) { WCN_DBG(FM_ERR | MAIN,"copy_to_user error\n"); ret = -EFAULT; goto out; } break; } case FM_IOCTL_RDSTX_ENABLE: { fm_s32 rds_tx_enable = -1; WCN_DBG(FM_NTC | MAIN,"......FM_IOCTL_RDSTX_ENABLE......\n"); ret = fm_rdstx_enable(fm,&rds_tx_enable); if(ret) { WCN_DBG(FM_ERR | MAIN, "fm_rdstx_enable err\n"); } if (copy_to_user((void*)arg, &rds_tx_enable, sizeof(fm_s32))) { WCN_DBG(FM_ERR | MAIN,"copy_to_user error\n"); ret = -EFAULT; goto out; } break; } case FM_IOCTL_RDS_TX: { struct fm_rds_tx_parm parm; WCN_DBG(FM_NTC | MAIN, "......FM_IOCTL_RDS_TX......\n"); if (copy_from_user(&parm, (void*)arg, sizeof(struct fm_rds_tx_parm))) { WCN_DBG(FM_ALT | MAIN, "RDS Tx, copy_from_user err\n"); ret = -EFAULT; goto out; } ret = fm_rds_tx(fm, &parm); if(ret) { WCN_DBG(FM_ALT | MAIN, "fm_rds_tx err\n"); } if (copy_to_user((void*)arg, &parm, sizeof(struct fm_rds_tx_parm))){ WCN_DBG(FM_ALT | MAIN, "RDS Tx, copy_to_user err\n"); ret = -EFAULT; goto out; } break; } case FM_IOCTL_TX_SCAN: { struct fm_tx_scan_parm parm; WCN_DBG(FM_NTC | MAIN, "......FM_IOCTL_TX_SCAN......\n"); if (copy_from_user(&parm, (void*)arg, sizeof(struct fm_tx_scan_parm))){ WCN_DBG(FM_ALT | MAIN,"copy_from_user error\n"); ret = -EFAULT; goto out; } ret = fm_tx_scan(fm, &parm); if(ret < 0){ WCN_DBG(FM_ERR | MAIN,"FM_IOCTL_TX_SCAN failed\n"); } if (copy_to_user((void*)arg, &parm, sizeof(struct fm_tx_scan_parm))){ WCN_DBG(FM_ALT | MAIN,"copy_to_user error\n"); ret = -EFAULT; goto out; } break; } default: ret = -EPERM; } out: if (ret == -FM_EFW) { // subsystem reset fm_subsys_reset(fm); } return ret; }
/*----------------------------------------------------------------------------*/ void fm_rev( void ) { u8 key; sys_mute_flag =0; PT2313_Config(sys_main_vol,VOL_ADJ); amp_mute(0); while (1) { #if ECHO_ENABLE dac_out_select(DAC_AMUX1 | ADD_DEC, 0); #else dac_out_select(DAC_AMUX1, 0); #endif key = app_get_msg(); switch (key) { case MSG_CHANGE_WORK_MODE: return; case MSG_MUSIC_NEW_DEVICE_IN: //有新设备接入 work_mode = MUSIC_MODE; return; case MSG_FM_SCAN_STOP: if(key_ir_detect){ key_ir_detect =0; ir_remote_set_snooze(); } break; case MSG_FM_SCAN_ALL: //play 长按自动全频搜索 key = fm_scan(0); if (key == 3) { put_msg_lifo(MSG_ALM_ON); break; } if (key == 2) return; put_msg_lifo(MSG_FM_NEXT_STATION); break; case MSG_FM_SCAN_ALL_DOWN : key = fm_scan(1); if (key == 3) { put_msg_lifo(MSG_ALM_ON); break; } if (key == 2) return; break; case MSG_FM_SCAN_ALL_UP: key =fm_scan(2); if (key == 3) { put_msg_lifo(MSG_ALM_ON); break; } if (key == 2) return; break; #if 0 case MSG_MUSIC_PP: //play 短按静音 put_msg_lifo(MSG_MUTE); break; case MSG_MUTE: break; #endif case MSG_MUSIC_FR: //搜索上一个台 flush_all_msg(); break; case MSG_MUSIC_FF: //搜索下一个台 flush_all_msg(); break; case MSG_FM_PREV_STEP: set_fre(FM_FRE_DEC); fre_channel = get_channel_via_fre(frequency - MIN_FRE); //查找该频点是否有记忆过 disp_port(MENU_FM_MAIN); write_info(MEM_FRE, frequency-MIN_FRE); write_info(MEM_CHAN, fre_channel); break; case MSG_FM_NEXT_STEP: set_fre(FM_FRE_INC); fre_channel = get_channel_via_fre(frequency - MIN_FRE); //查找该频点是否有记忆过 disp_port(MENU_FM_MAIN); write_info(MEM_FRE, frequency-MIN_FRE); write_info(MEM_CHAN, fre_channel); break; case MSG_FM_PREV_STATION: if (total_channel == 0) break; fre_channel -= 2; case MSG_FM_NEXT_STATION: if (total_channel == 0) break; fre_channel++; if ((fre_channel == 0) || (fre_channel == 0xff)) { fre_channel = total_channel; } else if (fre_channel > total_channel) { fre_channel = 1; } frequency = get_fre_via_channle(fre_channel) + MIN_FRE; //根据台号找频点 main_vol_set(0, CHANGE_VOL_NO_MEM); set_fre(FM_CUR_FRE); main_vol_set(0, SET_USE_CURRENT_VOL); disp_port(MENU_FM_CHANNEL); write_info(MEM_FRE, frequency-MIN_FRE); write_info(MEM_CHAN, fre_channel); break; case MSG_CH_SET: if (cur_menu == MENU_INPUT_NUMBER) //数字输入模式 { if (input_number <= MAX_CHANNL) //输入的是台号 { key = get_fre_via_channle(input_number); if (key != 0xff) { frequency = key + MIN_FRE; fre_channel = input_number; main_vol_set(0, CHANGE_VOL_NO_MEM); set_fre(FM_CUR_FRE); main_vol_set(0, SET_USE_CURRENT_VOL); disp_port(MENU_FM_CHANNEL); //break; } } else if ((input_number >= MIN_FRE) && (input_number <= MAX_FRE)) //输入的是频点 { frequency = input_number; fre_channel = get_channel_via_fre(frequency - MIN_FRE); main_vol_set(0, CHANGE_VOL_NO_MEM); set_fre(FM_CUR_FRE); main_vol_set(0, SET_USE_CURRENT_VOL); } } write_info(MEM_FRE, frequency-MIN_FRE); write_info(MEM_CHAN, fre_channel); disp_port(main_menu); break; case MSG_CH_SAVE: ch_save(); break; case MSG_HALF_SECOND: alarm_setting_vol_hdlr(); //bmt_hdlr(); timer_pwr_off_hdlr(); set_brightness_fade_out(); if (main_menu_conter < SUB_MENU_TIME) { main_menu_conter++; } else if (cur_menu != main_menu) { put_msg_lifo(MSG_CH_SET); //跳转至CH_SET消息处理 } if(cur_menu == main_menu) { disp_port(main_menu); } break; #if 0//RTC_ENABLE case MSG_ALM_ON: write_next_alm_sec(); work_mode = RTC_MODE; put_msg_lifo(MSG_CHANGE_WORK_MODE); break; #endif #if KALAOK_FUNCTION case MSG_KALAOK: work_mode = REC_MIC_MODE; return ; #endif default : ap_handle_hotkey(key); break; } } }