0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <linux/delay.h>
0010 #include "fmdrv.h"
0011 #include "fmdrv_common.h"
0012 #include "fmdrv_tx.h"
0013
0014 int fm_tx_set_stereo_mono(struct fmdev *fmdev, u16 mode)
0015 {
0016 u16 payload;
0017 int ret;
0018
0019 if (fmdev->tx_data.aud_mode == mode)
0020 return 0;
0021
0022 fmdbg("stereo mode: %d\n", mode);
0023
0024
0025 payload = (1 - mode);
0026 ret = fmc_send_cmd(fmdev, MONO_SET, REG_WR, &payload,
0027 sizeof(payload), NULL, NULL);
0028 if (ret < 0)
0029 return ret;
0030
0031 fmdev->tx_data.aud_mode = mode;
0032
0033 return ret;
0034 }
0035
0036 static int set_rds_text(struct fmdev *fmdev, u8 *rds_text)
0037 {
0038 u16 payload;
0039 int ret;
0040
0041 ret = fmc_send_cmd(fmdev, RDS_DATA_SET, REG_WR, rds_text,
0042 strlen(rds_text), NULL, NULL);
0043 if (ret < 0)
0044 return ret;
0045
0046
0047 payload = (u16)0x1;
0048 ret = fmc_send_cmd(fmdev, DISPLAY_MODE, REG_WR, &payload,
0049 sizeof(payload), NULL, NULL);
0050 if (ret < 0)
0051 return ret;
0052
0053 return 0;
0054 }
0055
0056 static int set_rds_data_mode(struct fmdev *fmdev, u8 mode)
0057 {
0058 u16 payload;
0059 int ret;
0060
0061
0062 payload = (u16)0xcafe;
0063 ret = fmc_send_cmd(fmdev, PI_SET, REG_WR, &payload,
0064 sizeof(payload), NULL, NULL);
0065 if (ret < 0)
0066 return ret;
0067
0068
0069 payload = (u16)0xa;
0070 ret = fmc_send_cmd(fmdev, DI_SET, REG_WR, &payload,
0071 sizeof(payload), NULL, NULL);
0072 if (ret < 0)
0073 return ret;
0074
0075
0076 return 0;
0077 }
0078
0079 static int set_rds_len(struct fmdev *fmdev, u8 type, u16 len)
0080 {
0081 u16 payload;
0082 int ret;
0083
0084 len |= type << 8;
0085 payload = len;
0086 ret = fmc_send_cmd(fmdev, RDS_CONFIG_DATA_SET, REG_WR, &payload,
0087 sizeof(payload), NULL, NULL);
0088 if (ret < 0)
0089 return ret;
0090
0091
0092 return 0;
0093 }
0094
0095 int fm_tx_set_rds_mode(struct fmdev *fmdev, u8 rds_en_dis)
0096 {
0097 u16 payload;
0098 int ret;
0099 u8 rds_text[] = "Zoom2\n";
0100
0101 fmdbg("rds_en_dis:%d(E:%d, D:%d)\n", rds_en_dis,
0102 FM_RDS_ENABLE, FM_RDS_DISABLE);
0103
0104 if (rds_en_dis == FM_RDS_ENABLE) {
0105
0106 set_rds_len(fmdev, 0, strlen(rds_text));
0107
0108
0109 set_rds_text(fmdev, rds_text);
0110
0111
0112 set_rds_data_mode(fmdev, 0x0);
0113 }
0114
0115
0116 if (rds_en_dis == FM_RDS_ENABLE)
0117 payload = 0x01;
0118 else
0119 payload = 0x00;
0120
0121 ret = fmc_send_cmd(fmdev, RDS_DATA_ENB, REG_WR, &payload,
0122 sizeof(payload), NULL, NULL);
0123 if (ret < 0)
0124 return ret;
0125
0126 if (rds_en_dis == FM_RDS_ENABLE) {
0127
0128 set_rds_len(fmdev, 0, strlen(rds_text));
0129
0130
0131 set_rds_text(fmdev, rds_text);
0132 }
0133 fmdev->tx_data.rds.flag = rds_en_dis;
0134
0135 return 0;
0136 }
0137
0138 int fm_tx_set_radio_text(struct fmdev *fmdev, u8 *rds_text, u8 rds_type)
0139 {
0140 u16 payload;
0141 int ret;
0142
0143 if (fmdev->curr_fmmode != FM_MODE_TX)
0144 return -EPERM;
0145
0146 fm_tx_set_rds_mode(fmdev, 0);
0147
0148
0149 set_rds_len(fmdev, rds_type, strlen(rds_text));
0150
0151
0152 set_rds_text(fmdev, rds_text);
0153
0154
0155 set_rds_data_mode(fmdev, 0x0);
0156
0157 payload = 1;
0158 ret = fmc_send_cmd(fmdev, RDS_DATA_ENB, REG_WR, &payload,
0159 sizeof(payload), NULL, NULL);
0160 if (ret < 0)
0161 return ret;
0162
0163 return 0;
0164 }
0165
0166 int fm_tx_set_af(struct fmdev *fmdev, u32 af)
0167 {
0168 u16 payload;
0169 int ret;
0170
0171 if (fmdev->curr_fmmode != FM_MODE_TX)
0172 return -EPERM;
0173
0174 fmdbg("AF: %d\n", af);
0175
0176 af = (af - 87500) / 100;
0177 payload = (u16)af;
0178 ret = fmc_send_cmd(fmdev, TA_SET, REG_WR, &payload,
0179 sizeof(payload), NULL, NULL);
0180 if (ret < 0)
0181 return ret;
0182
0183 return 0;
0184 }
0185
0186 int fm_tx_set_region(struct fmdev *fmdev, u8 region)
0187 {
0188 u16 payload;
0189 int ret;
0190
0191 if (region != FM_BAND_EUROPE_US && region != FM_BAND_JAPAN) {
0192 fmerr("Invalid band\n");
0193 return -EINVAL;
0194 }
0195
0196
0197 payload = (u16)region;
0198 ret = fmc_send_cmd(fmdev, TX_BAND_SET, REG_WR, &payload,
0199 sizeof(payload), NULL, NULL);
0200 if (ret < 0)
0201 return ret;
0202
0203 return 0;
0204 }
0205
0206 int fm_tx_set_mute_mode(struct fmdev *fmdev, u8 mute_mode_toset)
0207 {
0208 u16 payload;
0209 int ret;
0210
0211 fmdbg("tx: mute mode %d\n", mute_mode_toset);
0212
0213 payload = mute_mode_toset;
0214 ret = fmc_send_cmd(fmdev, MUTE, REG_WR, &payload,
0215 sizeof(payload), NULL, NULL);
0216 if (ret < 0)
0217 return ret;
0218
0219 return 0;
0220 }
0221
0222
0223 static int set_audio_io(struct fmdev *fmdev)
0224 {
0225 struct fmtx_data *tx = &fmdev->tx_data;
0226 u16 payload;
0227 int ret;
0228
0229
0230 payload = tx->audio_io;
0231 ret = fmc_send_cmd(fmdev, AUDIO_IO_SET, REG_WR, &payload,
0232 sizeof(payload), NULL, NULL);
0233 if (ret < 0)
0234 return ret;
0235
0236
0237 return 0;
0238 }
0239
0240
0241 static int enable_xmit(struct fmdev *fmdev, u8 new_xmit_state)
0242 {
0243 struct fmtx_data *tx = &fmdev->tx_data;
0244 unsigned long timeleft;
0245 u16 payload;
0246 int ret;
0247
0248
0249 payload = FM_POW_ENB_EVENT;
0250 ret = fmc_send_cmd(fmdev, INT_MASK_SET, REG_WR, &payload,
0251 sizeof(payload), NULL, NULL);
0252 if (ret < 0)
0253 return ret;
0254
0255
0256 payload = new_xmit_state;
0257 ret = fmc_send_cmd(fmdev, POWER_ENB_SET, REG_WR, &payload,
0258 sizeof(payload), NULL, NULL);
0259 if (ret < 0)
0260 return ret;
0261
0262
0263 init_completion(&fmdev->maintask_comp);
0264 timeleft = wait_for_completion_timeout(&fmdev->maintask_comp,
0265 FM_DRV_TX_TIMEOUT);
0266 if (!timeleft) {
0267 fmerr("Timeout(%d sec),didn't get tune ended interrupt\n",
0268 jiffies_to_msecs(FM_DRV_TX_TIMEOUT) / 1000);
0269 return -ETIMEDOUT;
0270 }
0271
0272 set_bit(FM_CORE_TX_XMITING, &fmdev->flag);
0273 tx->xmit_state = new_xmit_state;
0274
0275 return 0;
0276 }
0277
0278
0279 int fm_tx_set_pwr_lvl(struct fmdev *fmdev, u8 new_pwr_lvl)
0280 {
0281 u16 payload;
0282 struct fmtx_data *tx = &fmdev->tx_data;
0283 int ret;
0284
0285 if (fmdev->curr_fmmode != FM_MODE_TX)
0286 return -EPERM;
0287 fmdbg("tx: pwr_level_to_set %ld\n", (long int)new_pwr_lvl);
0288
0289
0290 if (!test_bit(FM_CORE_READY, &fmdev->flag)) {
0291 tx->pwr_lvl = new_pwr_lvl;
0292 return 0;
0293 }
0294
0295
0296
0297
0298
0299
0300
0301
0302 payload = (FM_PWR_LVL_HIGH - new_pwr_lvl);
0303 ret = fmc_send_cmd(fmdev, POWER_LEV_SET, REG_WR, &payload,
0304 sizeof(payload), NULL, NULL);
0305 if (ret < 0)
0306 return ret;
0307
0308
0309 tx->pwr_lvl = new_pwr_lvl;
0310
0311 return 0;
0312 }
0313
0314
0315
0316
0317
0318 int fm_tx_set_preemph_filter(struct fmdev *fmdev, u32 preemphasis)
0319 {
0320 struct fmtx_data *tx = &fmdev->tx_data;
0321 u16 payload;
0322 int ret;
0323
0324 if (fmdev->curr_fmmode != FM_MODE_TX)
0325 return -EPERM;
0326
0327 switch (preemphasis) {
0328 case V4L2_PREEMPHASIS_DISABLED:
0329 payload = FM_TX_PREEMPH_OFF;
0330 break;
0331 case V4L2_PREEMPHASIS_50_uS:
0332 payload = FM_TX_PREEMPH_50US;
0333 break;
0334 case V4L2_PREEMPHASIS_75_uS:
0335 payload = FM_TX_PREEMPH_75US;
0336 break;
0337 }
0338
0339 ret = fmc_send_cmd(fmdev, PREMPH_SET, REG_WR, &payload,
0340 sizeof(payload), NULL, NULL);
0341 if (ret < 0)
0342 return ret;
0343
0344 tx->preemph = payload;
0345
0346 return ret;
0347 }
0348
0349
0350 int fm_tx_get_tune_cap_val(struct fmdev *fmdev)
0351 {
0352 u16 curr_val;
0353 u32 resp_len;
0354 int ret;
0355
0356 if (fmdev->curr_fmmode != FM_MODE_TX)
0357 return -EPERM;
0358
0359 ret = fmc_send_cmd(fmdev, READ_FMANT_TUNE_VALUE, REG_RD,
0360 NULL, sizeof(curr_val), &curr_val, &resp_len);
0361 if (ret < 0)
0362 return ret;
0363
0364 curr_val = be16_to_cpu((__force __be16)curr_val);
0365
0366 return curr_val;
0367 }
0368
0369
0370 int fm_tx_set_freq(struct fmdev *fmdev, u32 freq_to_set)
0371 {
0372 struct fmtx_data *tx = &fmdev->tx_data;
0373 u16 payload, chanl_index;
0374 int ret;
0375
0376 if (test_bit(FM_CORE_TX_XMITING, &fmdev->flag)) {
0377 enable_xmit(fmdev, 0);
0378 clear_bit(FM_CORE_TX_XMITING, &fmdev->flag);
0379 }
0380
0381
0382 payload = (FM_FR_EVENT | FM_BL_EVENT);
0383 ret = fmc_send_cmd(fmdev, INT_MASK_SET, REG_WR, &payload,
0384 sizeof(payload), NULL, NULL);
0385 if (ret < 0)
0386 return ret;
0387
0388 tx->tx_frq = (unsigned long)freq_to_set;
0389 fmdbg("tx: freq_to_set %ld\n", (long int)tx->tx_frq);
0390
0391 chanl_index = freq_to_set / 10;
0392
0393
0394 payload = chanl_index;
0395 ret = fmc_send_cmd(fmdev, CHANL_SET, REG_WR, &payload,
0396 sizeof(payload), NULL, NULL);
0397 if (ret < 0)
0398 return ret;
0399
0400 fm_tx_set_pwr_lvl(fmdev, tx->pwr_lvl);
0401 fm_tx_set_preemph_filter(fmdev, tx->preemph);
0402
0403 tx->audio_io = 0x01;
0404 set_audio_io(fmdev);
0405
0406 enable_xmit(fmdev, 0x01);
0407
0408 tx->aud_mode = FM_STEREO_MODE;
0409 tx->rds.flag = FM_RDS_DISABLE;
0410
0411 return 0;
0412 }
0413