18b7a186cSManjunatha Halli /* 28b7a186cSManjunatha Halli * FM Driver for Connectivity chip of Texas Instruments. 38b7a186cSManjunatha Halli * This sub-module of FM driver implements FM TX functionality. 48b7a186cSManjunatha Halli * 58b7a186cSManjunatha Halli * Copyright (C) 2011 Texas Instruments 68b7a186cSManjunatha Halli * 78b7a186cSManjunatha Halli * This program is free software; you can redistribute it and/or modify 88b7a186cSManjunatha Halli * it under the terms of the GNU General Public License version 2 as 98b7a186cSManjunatha Halli * published by the Free Software Foundation. 108b7a186cSManjunatha Halli * 118b7a186cSManjunatha Halli * This program is distributed in the hope that it will be useful, 128b7a186cSManjunatha Halli * but WITHOUT ANY WARRANTY; without even the implied warranty of 138b7a186cSManjunatha Halli * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 148b7a186cSManjunatha Halli * GNU General Public License for more details. 158b7a186cSManjunatha Halli * 168b7a186cSManjunatha Halli * You should have received a copy of the GNU General Public License 178b7a186cSManjunatha Halli * along with this program; if not, write to the Free Software 188b7a186cSManjunatha Halli * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 198b7a186cSManjunatha Halli * 208b7a186cSManjunatha Halli */ 218b7a186cSManjunatha Halli 228b7a186cSManjunatha Halli #include <linux/delay.h> 238b7a186cSManjunatha Halli #include "fmdrv.h" 248b7a186cSManjunatha Halli #include "fmdrv_common.h" 258b7a186cSManjunatha Halli #include "fmdrv_tx.h" 268b7a186cSManjunatha Halli 278b7a186cSManjunatha Halli u32 fm_tx_set_stereo_mono(struct fmdev *fmdev, u16 mode) 288b7a186cSManjunatha Halli { 298b7a186cSManjunatha Halli u16 payload; 308b7a186cSManjunatha Halli u32 ret; 318b7a186cSManjunatha Halli 328b7a186cSManjunatha Halli if (fmdev->tx_data.aud_mode == mode) 338b7a186cSManjunatha Halli return 0; 348b7a186cSManjunatha Halli 358b7a186cSManjunatha Halli fmdbg("stereo mode: %d\n", mode); 368b7a186cSManjunatha Halli 378b7a186cSManjunatha Halli /* Set Stereo/Mono mode */ 388b7a186cSManjunatha Halli payload = (1 - mode); 398b7a186cSManjunatha Halli ret = fmc_send_cmd(fmdev, MONO_SET, REG_WR, &payload, 408b7a186cSManjunatha Halli sizeof(payload), NULL, NULL); 418b7a186cSManjunatha Halli if (ret < 0) 428b7a186cSManjunatha Halli return ret; 438b7a186cSManjunatha Halli 448b7a186cSManjunatha Halli fmdev->tx_data.aud_mode = mode; 458b7a186cSManjunatha Halli 468b7a186cSManjunatha Halli return ret; 478b7a186cSManjunatha Halli } 488b7a186cSManjunatha Halli 498b7a186cSManjunatha Halli static u32 set_rds_text(struct fmdev *fmdev, u8 *rds_text) 508b7a186cSManjunatha Halli { 518b7a186cSManjunatha Halli u16 payload; 528b7a186cSManjunatha Halli u32 ret; 538b7a186cSManjunatha Halli 548b7a186cSManjunatha Halli ret = fmc_send_cmd(fmdev, RDS_DATA_SET, REG_WR, rds_text, 558b7a186cSManjunatha Halli strlen(rds_text), NULL, NULL); 568b7a186cSManjunatha Halli if (ret < 0) 578b7a186cSManjunatha Halli return ret; 588b7a186cSManjunatha Halli 598b7a186cSManjunatha Halli /* Scroll mode */ 608b7a186cSManjunatha Halli payload = (u16)0x1; 618b7a186cSManjunatha Halli ret = fmc_send_cmd(fmdev, DISPLAY_MODE, REG_WR, &payload, 628b7a186cSManjunatha Halli sizeof(payload), NULL, NULL); 638b7a186cSManjunatha Halli if (ret < 0) 648b7a186cSManjunatha Halli return ret; 658b7a186cSManjunatha Halli 668b7a186cSManjunatha Halli return 0; 678b7a186cSManjunatha Halli } 688b7a186cSManjunatha Halli 698b7a186cSManjunatha Halli static u32 set_rds_data_mode(struct fmdev *fmdev, u8 mode) 708b7a186cSManjunatha Halli { 718b7a186cSManjunatha Halli u16 payload; 728b7a186cSManjunatha Halli u32 ret; 738b7a186cSManjunatha Halli 748b7a186cSManjunatha Halli /* Setting unique PI TODO: how unique? */ 758b7a186cSManjunatha Halli payload = (u16)0xcafe; 768b7a186cSManjunatha Halli ret = fmc_send_cmd(fmdev, PI_SET, REG_WR, &payload, 778b7a186cSManjunatha Halli sizeof(payload), NULL, NULL); 788b7a186cSManjunatha Halli if (ret < 0) 798b7a186cSManjunatha Halli return ret; 808b7a186cSManjunatha Halli 818b7a186cSManjunatha Halli /* Set decoder id */ 828b7a186cSManjunatha Halli payload = (u16)0xa; 838b7a186cSManjunatha Halli ret = fmc_send_cmd(fmdev, DI_SET, REG_WR, &payload, 848b7a186cSManjunatha Halli sizeof(payload), NULL, NULL); 858b7a186cSManjunatha Halli if (ret < 0) 868b7a186cSManjunatha Halli return ret; 878b7a186cSManjunatha Halli 888b7a186cSManjunatha Halli /* TODO: RDS_MODE_GET? */ 898b7a186cSManjunatha Halli return 0; 908b7a186cSManjunatha Halli } 918b7a186cSManjunatha Halli 928b7a186cSManjunatha Halli static u32 set_rds_len(struct fmdev *fmdev, u8 type, u16 len) 938b7a186cSManjunatha Halli { 948b7a186cSManjunatha Halli u16 payload; 958b7a186cSManjunatha Halli u32 ret; 968b7a186cSManjunatha Halli 978b7a186cSManjunatha Halli len |= type << 8; 988b7a186cSManjunatha Halli payload = len; 998b7a186cSManjunatha Halli ret = fmc_send_cmd(fmdev, RDS_CONFIG_DATA_SET, REG_WR, &payload, 1008b7a186cSManjunatha Halli sizeof(payload), NULL, NULL); 1018b7a186cSManjunatha Halli if (ret < 0) 1028b7a186cSManjunatha Halli return ret; 1038b7a186cSManjunatha Halli 1048b7a186cSManjunatha Halli /* TODO: LENGTH_GET? */ 1058b7a186cSManjunatha Halli return 0; 1068b7a186cSManjunatha Halli } 1078b7a186cSManjunatha Halli 1088b7a186cSManjunatha Halli u32 fm_tx_set_rds_mode(struct fmdev *fmdev, u8 rds_en_dis) 1098b7a186cSManjunatha Halli { 1108b7a186cSManjunatha Halli u16 payload; 1118b7a186cSManjunatha Halli u32 ret; 1128b7a186cSManjunatha Halli u8 rds_text[] = "Zoom2\n"; 1138b7a186cSManjunatha Halli 1148b7a186cSManjunatha Halli fmdbg("rds_en_dis:%d(E:%d, D:%d)\n", rds_en_dis, 1158b7a186cSManjunatha Halli FM_RDS_ENABLE, FM_RDS_DISABLE); 1168b7a186cSManjunatha Halli 1178b7a186cSManjunatha Halli if (rds_en_dis == FM_RDS_ENABLE) { 1188b7a186cSManjunatha Halli /* Set RDS length */ 1198b7a186cSManjunatha Halli set_rds_len(fmdev, 0, strlen(rds_text)); 1208b7a186cSManjunatha Halli 1218b7a186cSManjunatha Halli /* Set RDS text */ 1228b7a186cSManjunatha Halli set_rds_text(fmdev, rds_text); 1238b7a186cSManjunatha Halli 1248b7a186cSManjunatha Halli /* Set RDS mode */ 1258b7a186cSManjunatha Halli set_rds_data_mode(fmdev, 0x0); 1268b7a186cSManjunatha Halli } 1278b7a186cSManjunatha Halli 1288b7a186cSManjunatha Halli /* Send command to enable RDS */ 1298b7a186cSManjunatha Halli if (rds_en_dis == FM_RDS_ENABLE) 1308b7a186cSManjunatha Halli payload = 0x01; 1318b7a186cSManjunatha Halli else 1328b7a186cSManjunatha Halli payload = 0x00; 1338b7a186cSManjunatha Halli 1348b7a186cSManjunatha Halli ret = fmc_send_cmd(fmdev, RDS_DATA_ENB, REG_WR, &payload, 1358b7a186cSManjunatha Halli sizeof(payload), NULL, NULL); 1368b7a186cSManjunatha Halli if (ret < 0) 1378b7a186cSManjunatha Halli return ret; 1388b7a186cSManjunatha Halli 1398b7a186cSManjunatha Halli if (rds_en_dis == FM_RDS_ENABLE) { 1408b7a186cSManjunatha Halli /* Set RDS length */ 1418b7a186cSManjunatha Halli set_rds_len(fmdev, 0, strlen(rds_text)); 1428b7a186cSManjunatha Halli 1438b7a186cSManjunatha Halli /* Set RDS text */ 1448b7a186cSManjunatha Halli set_rds_text(fmdev, rds_text); 1458b7a186cSManjunatha Halli } 1468b7a186cSManjunatha Halli fmdev->tx_data.rds.flag = rds_en_dis; 1478b7a186cSManjunatha Halli 1488b7a186cSManjunatha Halli return 0; 1498b7a186cSManjunatha Halli } 1508b7a186cSManjunatha Halli 1518b7a186cSManjunatha Halli u32 fm_tx_set_radio_text(struct fmdev *fmdev, u8 *rds_text, u8 rds_type) 1528b7a186cSManjunatha Halli { 1538b7a186cSManjunatha Halli u16 payload; 1548b7a186cSManjunatha Halli u32 ret; 1558b7a186cSManjunatha Halli 1568b7a186cSManjunatha Halli if (fmdev->curr_fmmode != FM_MODE_TX) 1578b7a186cSManjunatha Halli return -EPERM; 1588b7a186cSManjunatha Halli 1598b7a186cSManjunatha Halli fm_tx_set_rds_mode(fmdev, 0); 1608b7a186cSManjunatha Halli 1618b7a186cSManjunatha Halli /* Set RDS length */ 1628b7a186cSManjunatha Halli set_rds_len(fmdev, rds_type, strlen(rds_text)); 1638b7a186cSManjunatha Halli 1648b7a186cSManjunatha Halli /* Set RDS text */ 1658b7a186cSManjunatha Halli set_rds_text(fmdev, rds_text); 1668b7a186cSManjunatha Halli 1678b7a186cSManjunatha Halli /* Set RDS mode */ 1688b7a186cSManjunatha Halli set_rds_data_mode(fmdev, 0x0); 1698b7a186cSManjunatha Halli 1708b7a186cSManjunatha Halli payload = 1; 1718b7a186cSManjunatha Halli ret = fmc_send_cmd(fmdev, RDS_DATA_ENB, REG_WR, &payload, 1728b7a186cSManjunatha Halli sizeof(payload), NULL, NULL); 1738b7a186cSManjunatha Halli if (ret < 0) 1748b7a186cSManjunatha Halli return ret; 1758b7a186cSManjunatha Halli 1768b7a186cSManjunatha Halli return 0; 1778b7a186cSManjunatha Halli } 1788b7a186cSManjunatha Halli 1798b7a186cSManjunatha Halli u32 fm_tx_set_af(struct fmdev *fmdev, u32 af) 1808b7a186cSManjunatha Halli { 1818b7a186cSManjunatha Halli u16 payload; 1828b7a186cSManjunatha Halli u32 ret; 1838b7a186cSManjunatha Halli 1848b7a186cSManjunatha Halli if (fmdev->curr_fmmode != FM_MODE_TX) 1858b7a186cSManjunatha Halli return -EPERM; 1868b7a186cSManjunatha Halli 1878b7a186cSManjunatha Halli fmdbg("AF: %d\n", af); 1888b7a186cSManjunatha Halli 1898b7a186cSManjunatha Halli af = (af - 87500) / 100; 1908b7a186cSManjunatha Halli payload = (u16)af; 1918b7a186cSManjunatha Halli ret = fmc_send_cmd(fmdev, TA_SET, REG_WR, &payload, 1928b7a186cSManjunatha Halli sizeof(payload), NULL, NULL); 1938b7a186cSManjunatha Halli if (ret < 0) 1948b7a186cSManjunatha Halli return ret; 1958b7a186cSManjunatha Halli 1968b7a186cSManjunatha Halli return 0; 1978b7a186cSManjunatha Halli } 1988b7a186cSManjunatha Halli 1998b7a186cSManjunatha Halli u32 fm_tx_set_region(struct fmdev *fmdev, u8 region) 2008b7a186cSManjunatha Halli { 2018b7a186cSManjunatha Halli u16 payload; 2028b7a186cSManjunatha Halli u32 ret; 2038b7a186cSManjunatha Halli 2048b7a186cSManjunatha Halli if (region != FM_BAND_EUROPE_US && region != FM_BAND_JAPAN) { 2058b7a186cSManjunatha Halli fmerr("Invalid band\n"); 2068b7a186cSManjunatha Halli return -EINVAL; 2078b7a186cSManjunatha Halli } 2088b7a186cSManjunatha Halli 2098b7a186cSManjunatha Halli /* Send command to set the band */ 2108b7a186cSManjunatha Halli payload = (u16)region; 2118b7a186cSManjunatha Halli ret = fmc_send_cmd(fmdev, TX_BAND_SET, REG_WR, &payload, 2128b7a186cSManjunatha Halli sizeof(payload), NULL, NULL); 2138b7a186cSManjunatha Halli if (ret < 0) 2148b7a186cSManjunatha Halli return ret; 2158b7a186cSManjunatha Halli 2168b7a186cSManjunatha Halli return 0; 2178b7a186cSManjunatha Halli } 2188b7a186cSManjunatha Halli 2198b7a186cSManjunatha Halli u32 fm_tx_set_mute_mode(struct fmdev *fmdev, u8 mute_mode_toset) 2208b7a186cSManjunatha Halli { 2218b7a186cSManjunatha Halli u16 payload; 2228b7a186cSManjunatha Halli u32 ret; 2238b7a186cSManjunatha Halli 2248b7a186cSManjunatha Halli fmdbg("tx: mute mode %d\n", mute_mode_toset); 2258b7a186cSManjunatha Halli 2268b7a186cSManjunatha Halli payload = mute_mode_toset; 2278b7a186cSManjunatha Halli ret = fmc_send_cmd(fmdev, MUTE, REG_WR, &payload, 2288b7a186cSManjunatha Halli sizeof(payload), NULL, NULL); 2298b7a186cSManjunatha Halli if (ret < 0) 2308b7a186cSManjunatha Halli return ret; 2318b7a186cSManjunatha Halli 2328b7a186cSManjunatha Halli return 0; 2338b7a186cSManjunatha Halli } 2348b7a186cSManjunatha Halli 2358b7a186cSManjunatha Halli /* Set TX Audio I/O */ 2368b7a186cSManjunatha Halli static u32 set_audio_io(struct fmdev *fmdev) 2378b7a186cSManjunatha Halli { 2388b7a186cSManjunatha Halli struct fmtx_data *tx = &fmdev->tx_data; 2398b7a186cSManjunatha Halli u16 payload; 2408b7a186cSManjunatha Halli u32 ret; 2418b7a186cSManjunatha Halli 2428b7a186cSManjunatha Halli /* Set Audio I/O Enable */ 2438b7a186cSManjunatha Halli payload = tx->audio_io; 2448b7a186cSManjunatha Halli ret = fmc_send_cmd(fmdev, AUDIO_IO_SET, REG_WR, &payload, 2458b7a186cSManjunatha Halli sizeof(payload), NULL, NULL); 2468b7a186cSManjunatha Halli if (ret < 0) 2478b7a186cSManjunatha Halli return ret; 2488b7a186cSManjunatha Halli 2498b7a186cSManjunatha Halli /* TODO: is audio set? */ 2508b7a186cSManjunatha Halli return 0; 2518b7a186cSManjunatha Halli } 2528b7a186cSManjunatha Halli 2538b7a186cSManjunatha Halli /* Start TX Transmission */ 2548b7a186cSManjunatha Halli static u32 enable_xmit(struct fmdev *fmdev, u8 new_xmit_state) 2558b7a186cSManjunatha Halli { 2568b7a186cSManjunatha Halli struct fmtx_data *tx = &fmdev->tx_data; 2578b7a186cSManjunatha Halli unsigned long timeleft; 2588b7a186cSManjunatha Halli u16 payload; 2598b7a186cSManjunatha Halli u32 ret; 2608b7a186cSManjunatha Halli 2618b7a186cSManjunatha Halli /* Enable POWER_ENB interrupts */ 2628b7a186cSManjunatha Halli payload = FM_POW_ENB_EVENT; 2638b7a186cSManjunatha Halli ret = fmc_send_cmd(fmdev, INT_MASK_SET, REG_WR, &payload, 2648b7a186cSManjunatha Halli sizeof(payload), NULL, NULL); 2658b7a186cSManjunatha Halli if (ret < 0) 2668b7a186cSManjunatha Halli return ret; 2678b7a186cSManjunatha Halli 2688b7a186cSManjunatha Halli /* Set Power Enable */ 2698b7a186cSManjunatha Halli payload = new_xmit_state; 2708b7a186cSManjunatha Halli ret = fmc_send_cmd(fmdev, POWER_ENB_SET, REG_WR, &payload, 2718b7a186cSManjunatha Halli sizeof(payload), NULL, NULL); 2728b7a186cSManjunatha Halli if (ret < 0) 2738b7a186cSManjunatha Halli return ret; 2748b7a186cSManjunatha Halli 2758b7a186cSManjunatha Halli /* Wait for Power Enabled */ 2768b7a186cSManjunatha Halli init_completion(&fmdev->maintask_comp); 2778b7a186cSManjunatha Halli timeleft = wait_for_completion_timeout(&fmdev->maintask_comp, 2788b7a186cSManjunatha Halli FM_DRV_TX_TIMEOUT); 2798b7a186cSManjunatha Halli if (!timeleft) { 2808b7a186cSManjunatha Halli fmerr("Timeout(%d sec),didn't get tune ended interrupt\n", 2818b7a186cSManjunatha Halli jiffies_to_msecs(FM_DRV_TX_TIMEOUT) / 1000); 2828b7a186cSManjunatha Halli return -ETIMEDOUT; 2838b7a186cSManjunatha Halli } 2848b7a186cSManjunatha Halli 2858b7a186cSManjunatha Halli set_bit(FM_CORE_TX_XMITING, &fmdev->flag); 2868b7a186cSManjunatha Halli tx->xmit_state = new_xmit_state; 2878b7a186cSManjunatha Halli 2888b7a186cSManjunatha Halli return 0; 2898b7a186cSManjunatha Halli } 2908b7a186cSManjunatha Halli 2918b7a186cSManjunatha Halli /* Set TX power level */ 2928b7a186cSManjunatha Halli u32 fm_tx_set_pwr_lvl(struct fmdev *fmdev, u8 new_pwr_lvl) 2938b7a186cSManjunatha Halli { 2948b7a186cSManjunatha Halli u16 payload; 2958b7a186cSManjunatha Halli struct fmtx_data *tx = &fmdev->tx_data; 2968b7a186cSManjunatha Halli u32 ret; 2978b7a186cSManjunatha Halli 2988b7a186cSManjunatha Halli if (fmdev->curr_fmmode != FM_MODE_TX) 2998b7a186cSManjunatha Halli return -EPERM; 3008b7a186cSManjunatha Halli fmdbg("tx: pwr_level_to_set %ld\n", (long int)new_pwr_lvl); 3018b7a186cSManjunatha Halli 3028b7a186cSManjunatha Halli /* If the core isn't ready update global variable */ 3038b7a186cSManjunatha Halli if (!test_bit(FM_CORE_READY, &fmdev->flag)) { 3048b7a186cSManjunatha Halli tx->pwr_lvl = new_pwr_lvl; 3058b7a186cSManjunatha Halli return 0; 3068b7a186cSManjunatha Halli } 3078b7a186cSManjunatha Halli 3088b7a186cSManjunatha Halli /* Set power level: Application will specify power level value in 3098b7a186cSManjunatha Halli * units of dB/uV, whereas range and step are specific to FM chip. 3108b7a186cSManjunatha Halli * For TI's WL chips, convert application specified power level value 3118b7a186cSManjunatha Halli * to chip specific value by subtracting 122 from it. Refer to TI FM 3128b7a186cSManjunatha Halli * data sheet for details. 3138b7a186cSManjunatha Halli * */ 3148b7a186cSManjunatha Halli 3158b7a186cSManjunatha Halli payload = (FM_PWR_LVL_HIGH - new_pwr_lvl); 3168b7a186cSManjunatha Halli ret = fmc_send_cmd(fmdev, POWER_LEV_SET, REG_WR, &payload, 3178b7a186cSManjunatha Halli sizeof(payload), NULL, NULL); 3188b7a186cSManjunatha Halli if (ret < 0) 3198b7a186cSManjunatha Halli return ret; 3208b7a186cSManjunatha Halli 3218b7a186cSManjunatha Halli /* TODO: is the power level set? */ 3228b7a186cSManjunatha Halli tx->pwr_lvl = new_pwr_lvl; 3238b7a186cSManjunatha Halli 3248b7a186cSManjunatha Halli return 0; 3258b7a186cSManjunatha Halli } 3268b7a186cSManjunatha Halli 3278b7a186cSManjunatha Halli /* 3288b7a186cSManjunatha Halli * Sets FM TX pre-emphasis filter value (OFF, 50us, or 75us) 3298b7a186cSManjunatha Halli * Convert V4L2 specified filter values to chip specific filter values. 3308b7a186cSManjunatha Halli */ 3318b7a186cSManjunatha Halli u32 fm_tx_set_preemph_filter(struct fmdev *fmdev, u32 preemphasis) 3328b7a186cSManjunatha Halli { 3338b7a186cSManjunatha Halli struct fmtx_data *tx = &fmdev->tx_data; 3348b7a186cSManjunatha Halli u16 payload; 3358b7a186cSManjunatha Halli u32 ret; 3368b7a186cSManjunatha Halli 3378b7a186cSManjunatha Halli if (fmdev->curr_fmmode != FM_MODE_TX) 3388b7a186cSManjunatha Halli return -EPERM; 3398b7a186cSManjunatha Halli 3408b7a186cSManjunatha Halli switch (preemphasis) { 3418b7a186cSManjunatha Halli case V4L2_PREEMPHASIS_DISABLED: 3428b7a186cSManjunatha Halli payload = FM_TX_PREEMPH_OFF; 3438b7a186cSManjunatha Halli break; 3448b7a186cSManjunatha Halli case V4L2_PREEMPHASIS_50_uS: 3458b7a186cSManjunatha Halli payload = FM_TX_PREEMPH_50US; 3468b7a186cSManjunatha Halli break; 3478b7a186cSManjunatha Halli case V4L2_PREEMPHASIS_75_uS: 3488b7a186cSManjunatha Halli payload = FM_TX_PREEMPH_75US; 3498b7a186cSManjunatha Halli break; 3508b7a186cSManjunatha Halli } 3518b7a186cSManjunatha Halli 3528b7a186cSManjunatha Halli ret = fmc_send_cmd(fmdev, PREMPH_SET, REG_WR, &payload, 3538b7a186cSManjunatha Halli sizeof(payload), NULL, NULL); 3548b7a186cSManjunatha Halli if (ret < 0) 3558b7a186cSManjunatha Halli return ret; 3568b7a186cSManjunatha Halli 3578b7a186cSManjunatha Halli tx->preemph = payload; 3588b7a186cSManjunatha Halli 3598b7a186cSManjunatha Halli return ret; 3608b7a186cSManjunatha Halli } 3618b7a186cSManjunatha Halli 3628b7a186cSManjunatha Halli /* Get the TX tuning capacitor value.*/ 3638b7a186cSManjunatha Halli u32 fm_tx_get_tune_cap_val(struct fmdev *fmdev) 3648b7a186cSManjunatha Halli { 3658b7a186cSManjunatha Halli u16 curr_val; 3668b7a186cSManjunatha Halli u32 ret, resp_len; 3678b7a186cSManjunatha Halli 3688b7a186cSManjunatha Halli if (fmdev->curr_fmmode != FM_MODE_TX) 3698b7a186cSManjunatha Halli return -EPERM; 3708b7a186cSManjunatha Halli 3718b7a186cSManjunatha Halli ret = fmc_send_cmd(fmdev, READ_FMANT_TUNE_VALUE, REG_RD, 3728b7a186cSManjunatha Halli NULL, sizeof(curr_val), &curr_val, &resp_len); 3738b7a186cSManjunatha Halli if (ret < 0) 3748b7a186cSManjunatha Halli return ret; 3758b7a186cSManjunatha Halli 3768b7a186cSManjunatha Halli curr_val = be16_to_cpu(curr_val); 3778b7a186cSManjunatha Halli 3788b7a186cSManjunatha Halli return curr_val; 3798b7a186cSManjunatha Halli } 3808b7a186cSManjunatha Halli 3818b7a186cSManjunatha Halli /* Set TX Frequency */ 3828b7a186cSManjunatha Halli u32 fm_tx_set_freq(struct fmdev *fmdev, u32 freq_to_set) 3838b7a186cSManjunatha Halli { 3848b7a186cSManjunatha Halli struct fmtx_data *tx = &fmdev->tx_data; 3858b7a186cSManjunatha Halli u16 payload, chanl_index; 3868b7a186cSManjunatha Halli u32 ret; 3878b7a186cSManjunatha Halli 3888b7a186cSManjunatha Halli if (test_bit(FM_CORE_TX_XMITING, &fmdev->flag)) { 3898b7a186cSManjunatha Halli enable_xmit(fmdev, 0); 3908b7a186cSManjunatha Halli clear_bit(FM_CORE_TX_XMITING, &fmdev->flag); 3918b7a186cSManjunatha Halli } 3928b7a186cSManjunatha Halli 3938b7a186cSManjunatha Halli /* Enable FR, BL interrupts */ 3948b7a186cSManjunatha Halli payload = (FM_FR_EVENT | FM_BL_EVENT); 3958b7a186cSManjunatha Halli ret = fmc_send_cmd(fmdev, INT_MASK_SET, REG_WR, &payload, 3968b7a186cSManjunatha Halli sizeof(payload), NULL, NULL); 3978b7a186cSManjunatha Halli if (ret < 0) 3988b7a186cSManjunatha Halli return ret; 3998b7a186cSManjunatha Halli 4008b7a186cSManjunatha Halli tx->tx_frq = (unsigned long)freq_to_set; 4018b7a186cSManjunatha Halli fmdbg("tx: freq_to_set %ld\n", (long int)tx->tx_frq); 4028b7a186cSManjunatha Halli 4038b7a186cSManjunatha Halli chanl_index = freq_to_set / 10; 4048b7a186cSManjunatha Halli 4058b7a186cSManjunatha Halli /* Set current tuner channel */ 4068b7a186cSManjunatha Halli payload = chanl_index; 4078b7a186cSManjunatha Halli ret = fmc_send_cmd(fmdev, CHANL_SET, REG_WR, &payload, 4088b7a186cSManjunatha Halli sizeof(payload), NULL, NULL); 4098b7a186cSManjunatha Halli if (ret < 0) 4108b7a186cSManjunatha Halli return ret; 4118b7a186cSManjunatha Halli 4128b7a186cSManjunatha Halli fm_tx_set_pwr_lvl(fmdev, tx->pwr_lvl); 4138b7a186cSManjunatha Halli fm_tx_set_preemph_filter(fmdev, tx->preemph); 4148b7a186cSManjunatha Halli 4158b7a186cSManjunatha Halli tx->audio_io = 0x01; /* I2S */ 4168b7a186cSManjunatha Halli set_audio_io(fmdev); 4178b7a186cSManjunatha Halli 4188b7a186cSManjunatha Halli enable_xmit(fmdev, 0x01); /* Enable transmission */ 4198b7a186cSManjunatha Halli 4208b7a186cSManjunatha Halli tx->aud_mode = FM_STEREO_MODE; 4218b7a186cSManjunatha Halli tx->rds.flag = FM_RDS_DISABLE; 4228b7a186cSManjunatha Halli 4238b7a186cSManjunatha Halli return 0; 4248b7a186cSManjunatha Halli } 4258b7a186cSManjunatha Halli 426