1156 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * Programming the mspx4xx sound processor family4 *5 * (c) 1997-2001 Gerd Knorr <kraxel@bytesex.org>6 */7 8 9#include <linux/kernel.h>10#include <linux/module.h>11#include <linux/i2c.h>12#include <linux/freezer.h>13#include <linux/videodev2.h>14#include <media/v4l2-common.h>15#include <media/drv-intf/msp3400.h>16#include <linux/kthread.h>17#include <linux/suspend.h>18#include "msp3400-driver.h"19 20/* this one uses the automatic sound standard detection of newer msp34xx21 chip versions */22static struct {23 int retval;24 int main, second;25 char *name;26 v4l2_std_id std;27} msp_stdlist[] = {28 { 0x0000, 0, 0, "could not detect sound standard", V4L2_STD_ALL },29 { 0x0001, 0, 0, "autodetect start", V4L2_STD_ALL },30 { 0x0002, MSP_CARRIER(4.5), MSP_CARRIER(4.72),31 "4.5/4.72 M Dual FM-Stereo", V4L2_STD_MN },32 { 0x0003, MSP_CARRIER(5.5), MSP_CARRIER(5.7421875),33 "5.5/5.74 B/G Dual FM-Stereo", V4L2_STD_BG },34 { 0x0004, MSP_CARRIER(6.5), MSP_CARRIER(6.2578125),35 "6.5/6.25 D/K1 Dual FM-Stereo", V4L2_STD_DK },36 { 0x0005, MSP_CARRIER(6.5), MSP_CARRIER(6.7421875),37 "6.5/6.74 D/K2 Dual FM-Stereo", V4L2_STD_DK },38 { 0x0006, MSP_CARRIER(6.5), MSP_CARRIER(6.5),39 "6.5 D/K FM-Mono (HDEV3)", V4L2_STD_DK },40 { 0x0007, MSP_CARRIER(6.5), MSP_CARRIER(5.7421875),41 "6.5/5.74 D/K3 Dual FM-Stereo", V4L2_STD_DK },42 { 0x0008, MSP_CARRIER(5.5), MSP_CARRIER(5.85),43 "5.5/5.85 B/G NICAM FM", V4L2_STD_BG },44 { 0x0009, MSP_CARRIER(6.5), MSP_CARRIER(5.85),45 "6.5/5.85 L NICAM AM", V4L2_STD_L },46 { 0x000a, MSP_CARRIER(6.0), MSP_CARRIER(6.55),47 "6.0/6.55 I NICAM FM", V4L2_STD_PAL_I },48 { 0x000b, MSP_CARRIER(6.5), MSP_CARRIER(5.85),49 "6.5/5.85 D/K NICAM FM", V4L2_STD_DK },50 { 0x000c, MSP_CARRIER(6.5), MSP_CARRIER(5.85),51 "6.5/5.85 D/K NICAM FM (HDEV2)", V4L2_STD_DK },52 { 0x000d, MSP_CARRIER(6.5), MSP_CARRIER(5.85),53 "6.5/5.85 D/K NICAM FM (HDEV3)", V4L2_STD_DK },54 { 0x0020, MSP_CARRIER(4.5), MSP_CARRIER(4.5),55 "4.5 M BTSC-Stereo", V4L2_STD_MTS },56 { 0x0021, MSP_CARRIER(4.5), MSP_CARRIER(4.5),57 "4.5 M BTSC-Mono + SAP", V4L2_STD_MTS },58 { 0x0030, MSP_CARRIER(4.5), MSP_CARRIER(4.5),59 "4.5 M EIA-J Japan Stereo", V4L2_STD_NTSC_M_JP },60 { 0x0040, MSP_CARRIER(10.7), MSP_CARRIER(10.7),61 "10.7 FM-Stereo Radio", V4L2_STD_ALL },62 { 0x0050, MSP_CARRIER(6.5), MSP_CARRIER(6.5),63 "6.5 SAT-Mono", V4L2_STD_ALL },64 { 0x0051, MSP_CARRIER(7.02), MSP_CARRIER(7.20),65 "7.02/7.20 SAT-Stereo", V4L2_STD_ALL },66 { 0x0060, MSP_CARRIER(7.2), MSP_CARRIER(7.2),67 "7.2 SAT ADR", V4L2_STD_ALL },68 { -1, 0, 0, NULL, 0 }, /* EOF */69};70 71static struct msp3400c_init_data_dem {72 int fir1[6];73 int fir2[6];74 int cdo1;75 int cdo2;76 int ad_cv;77 int mode_reg;78 int dsp_src;79 int dsp_matrix;80} msp3400c_init_data[] = {81 { /* AM (for carrier detect / msp3400) */82 {75, 19, 36, 35, 39, 40},83 {75, 19, 36, 35, 39, 40},84 MSP_CARRIER(5.5), MSP_CARRIER(5.5),85 0x00d0, 0x0500, 0x0020, 0x300086 }, { /* AM (for carrier detect / msp3410) */87 {-1, -1, -8, 2, 59, 126},88 {-1, -1, -8, 2, 59, 126},89 MSP_CARRIER(5.5), MSP_CARRIER(5.5),90 0x00d0, 0x0100, 0x0020, 0x300091 }, { /* FM Radio */92 {-8, -8, 4, 6, 78, 107},93 {-8, -8, 4, 6, 78, 107},94 MSP_CARRIER(10.7), MSP_CARRIER(10.7),95 0x00d0, 0x0480, 0x0020, 0x300096 }, { /* Terrestrial FM-mono + FM-stereo */97 {3, 18, 27, 48, 66, 72},98 {3, 18, 27, 48, 66, 72},99 MSP_CARRIER(5.5), MSP_CARRIER(5.5),100 0x00d0, 0x0480, 0x0030, 0x3000101 }, { /* Sat FM-mono */102 { 1, 9, 14, 24, 33, 37},103 { 3, 18, 27, 48, 66, 72},104 MSP_CARRIER(6.5), MSP_CARRIER(6.5),105 0x00c6, 0x0480, 0x0000, 0x3000106 }, { /* NICAM/FM -- B/G (5.5/5.85), D/K (6.5/5.85) */107 {-2, -8, -10, 10, 50, 86},108 {3, 18, 27, 48, 66, 72},109 MSP_CARRIER(5.5), MSP_CARRIER(5.5),110 0x00d0, 0x0040, 0x0120, 0x3000111 }, { /* NICAM/FM -- I (6.0/6.552) */112 {2, 4, -6, -4, 40, 94},113 {3, 18, 27, 48, 66, 72},114 MSP_CARRIER(6.0), MSP_CARRIER(6.0),115 0x00d0, 0x0040, 0x0120, 0x3000116 }, { /* NICAM/AM -- L (6.5/5.85) */117 {-2, -8, -10, 10, 50, 86},118 {-4, -12, -9, 23, 79, 126},119 MSP_CARRIER(6.5), MSP_CARRIER(6.5),120 0x00c6, 0x0140, 0x0120, 0x7c00121 },122};123 124struct msp3400c_carrier_detect {125 int cdo;126 char *name;127};128 129static struct msp3400c_carrier_detect msp3400c_carrier_detect_main[] = {130 /* main carrier */131 { MSP_CARRIER(4.5), "4.5 NTSC" },132 { MSP_CARRIER(5.5), "5.5 PAL B/G" },133 { MSP_CARRIER(6.0), "6.0 PAL I" },134 { MSP_CARRIER(6.5), "6.5 PAL D/K + SAT + SECAM" }135};136 137static struct msp3400c_carrier_detect msp3400c_carrier_detect_55[] = {138 /* PAL B/G */139 { MSP_CARRIER(5.7421875), "5.742 PAL B/G FM-stereo" },140 { MSP_CARRIER(5.85), "5.85 PAL B/G NICAM" }141};142 143static struct msp3400c_carrier_detect msp3400c_carrier_detect_65[] = {144 /* PAL SAT / SECAM */145 { MSP_CARRIER(5.85), "5.85 PAL D/K + SECAM NICAM" },146 { MSP_CARRIER(6.2578125), "6.25 PAL D/K1 FM-stereo" },147 { MSP_CARRIER(6.7421875), "6.74 PAL D/K2 FM-stereo" },148 { MSP_CARRIER(7.02), "7.02 PAL SAT FM-stereo s/b" },149 { MSP_CARRIER(7.20), "7.20 PAL SAT FM-stereo s" },150 { MSP_CARRIER(7.38), "7.38 PAL SAT FM-stereo b" },151};152 153/* ------------------------------------------------------------------------ */154 155const char *msp_standard_std_name(int std)156{157 int i;158 159 for (i = 0; msp_stdlist[i].name != NULL; i++)160 if (msp_stdlist[i].retval == std)161 return msp_stdlist[i].name;162 return "unknown";163}164 165static v4l2_std_id msp_standard_std(int std)166{167 int i;168 169 for (i = 0; msp_stdlist[i].name != NULL; i++)170 if (msp_stdlist[i].retval == std)171 return msp_stdlist[i].std;172 return V4L2_STD_ALL;173}174 175static void msp_set_source(struct i2c_client *client, u16 src)176{177 struct msp_state *state = to_state(i2c_get_clientdata(client));178 179 if (msp_dolby) {180 msp_write_dsp(client, 0x0008, 0x0520); /* I2S1 */181 msp_write_dsp(client, 0x0009, 0x0620); /* I2S2 */182 } else {183 msp_write_dsp(client, 0x0008, src);184 msp_write_dsp(client, 0x0009, src);185 }186 msp_write_dsp(client, 0x000a, src);187 msp_write_dsp(client, 0x000b, src);188 msp_write_dsp(client, 0x000c, src);189 if (state->has_scart2_out)190 msp_write_dsp(client, 0x0041, src);191}192 193void msp3400c_set_carrier(struct i2c_client *client, int cdo1, int cdo2)194{195 msp_write_dem(client, 0x0093, cdo1 & 0xfff);196 msp_write_dem(client, 0x009b, cdo1 >> 12);197 msp_write_dem(client, 0x00a3, cdo2 & 0xfff);198 msp_write_dem(client, 0x00ab, cdo2 >> 12);199 msp_write_dem(client, 0x0056, 0); /* LOAD_REG_1/2 */200}201 202void msp3400c_set_mode(struct i2c_client *client, int mode)203{204 struct msp_state *state = to_state(i2c_get_clientdata(client));205 struct msp3400c_init_data_dem *data = &msp3400c_init_data[mode];206 int tuner = (state->route_in >> 3) & 1;207 int i;208 209 dev_dbg_lvl(&client->dev, 1, msp_debug, "set_mode: %d\n", mode);210 state->mode = mode;211 state->rxsubchans = V4L2_TUNER_SUB_MONO;212 213 msp_write_dem(client, 0x00bb, data->ad_cv | (tuner ? 0x100 : 0));214 215 for (i = 5; i >= 0; i--) /* fir 1 */216 msp_write_dem(client, 0x0001, data->fir1[i]);217 218 msp_write_dem(client, 0x0005, 0x0004); /* fir 2 */219 msp_write_dem(client, 0x0005, 0x0040);220 msp_write_dem(client, 0x0005, 0x0000);221 for (i = 5; i >= 0; i--)222 msp_write_dem(client, 0x0005, data->fir2[i]);223 224 msp_write_dem(client, 0x0083, data->mode_reg);225 226 msp3400c_set_carrier(client, data->cdo1, data->cdo2);227 228 msp_set_source(client, data->dsp_src);229 /* set prescales */230 231 /* volume prescale for SCART (AM mono input) */232 msp_write_dsp(client, 0x000d, 0x1900);233 msp_write_dsp(client, 0x000e, data->dsp_matrix);234 if (state->has_nicam) /* nicam prescale */235 msp_write_dsp(client, 0x0010, 0x5a00);236}237 238/* Set audio mode. Note that the pre-'G' models do not support BTSC+SAP,239 nor do they support stereo BTSC. */240static void msp3400c_set_audmode(struct i2c_client *client)241{242 static char *strmode[] = {243 "mono", "stereo", "lang2", "lang1", "lang1+lang2"244 };245 struct msp_state *state = to_state(i2c_get_clientdata(client));246 char *modestr = (state->audmode >= 0 && state->audmode < 5) ?247 strmode[state->audmode] : "unknown";248 int src = 0; /* channel source: FM/AM, nicam or SCART */249 int audmode = state->audmode;250 251 if (state->opmode == OPMODE_AUTOSELECT) {252 /* this method would break everything, let's make sure253 * it's never called254 */255 dev_dbg_lvl(&client->dev, 1, msp_debug,256 "set_audmode called with mode=%d instead of set_source (ignored)\n",257 state->audmode);258 return;259 }260 261 /* Note: for the C and D revs no NTSC stereo + SAP is possible as262 the hardware does not support SAP. So the rxsubchans combination263 of STEREO | LANG2 does not occur. */264 265 if (state->mode != MSP_MODE_EXTERN) {266 /* switch to mono if only mono is available */267 if (state->rxsubchans == V4L2_TUNER_SUB_MONO)268 audmode = V4L2_TUNER_MODE_MONO;269 /* if bilingual */270 else if (state->rxsubchans & V4L2_TUNER_SUB_LANG2) {271 /* and mono or stereo, then fallback to lang1 */272 if (audmode == V4L2_TUNER_MODE_MONO ||273 audmode == V4L2_TUNER_MODE_STEREO)274 audmode = V4L2_TUNER_MODE_LANG1;275 }276 /* if stereo, and audmode is not mono, then switch to stereo */277 else if (audmode != V4L2_TUNER_MODE_MONO)278 audmode = V4L2_TUNER_MODE_STEREO;279 }280 281 /* switch demodulator */282 switch (state->mode) {283 case MSP_MODE_FM_TERRA:284 dev_dbg_lvl(&client->dev, 1, msp_debug, "FM set_audmode: %s\n", modestr);285 switch (audmode) {286 case V4L2_TUNER_MODE_STEREO:287 msp_write_dsp(client, 0x000e, 0x3001);288 break;289 case V4L2_TUNER_MODE_MONO:290 case V4L2_TUNER_MODE_LANG1:291 case V4L2_TUNER_MODE_LANG2:292 case V4L2_TUNER_MODE_LANG1_LANG2:293 msp_write_dsp(client, 0x000e, 0x3000);294 break;295 }296 break;297 case MSP_MODE_FM_SAT:298 dev_dbg_lvl(&client->dev, 1, msp_debug, "SAT set_audmode: %s\n", modestr);299 switch (audmode) {300 case V4L2_TUNER_MODE_MONO:301 msp3400c_set_carrier(client, MSP_CARRIER(6.5), MSP_CARRIER(6.5));302 break;303 case V4L2_TUNER_MODE_STEREO:304 case V4L2_TUNER_MODE_LANG1_LANG2:305 msp3400c_set_carrier(client, MSP_CARRIER(7.2), MSP_CARRIER(7.02));306 break;307 case V4L2_TUNER_MODE_LANG1:308 msp3400c_set_carrier(client, MSP_CARRIER(7.38), MSP_CARRIER(7.02));309 break;310 case V4L2_TUNER_MODE_LANG2:311 msp3400c_set_carrier(client, MSP_CARRIER(7.38), MSP_CARRIER(7.02));312 break;313 }314 break;315 case MSP_MODE_FM_NICAM1:316 case MSP_MODE_FM_NICAM2:317 case MSP_MODE_AM_NICAM:318 dev_dbg_lvl(&client->dev, 1, msp_debug,319 "NICAM set_audmode: %s\n", modestr);320 if (state->nicam_on)321 src = 0x0100; /* NICAM */322 break;323 case MSP_MODE_BTSC:324 dev_dbg_lvl(&client->dev, 1, msp_debug,325 "BTSC set_audmode: %s\n", modestr);326 break;327 case MSP_MODE_EXTERN:328 dev_dbg_lvl(&client->dev, 1, msp_debug,329 "extern set_audmode: %s\n", modestr);330 src = 0x0200; /* SCART */331 break;332 case MSP_MODE_FM_RADIO:333 dev_dbg_lvl(&client->dev, 1, msp_debug,334 "FM-Radio set_audmode: %s\n", modestr);335 break;336 default:337 dev_dbg_lvl(&client->dev, 1, msp_debug, "mono set_audmode\n");338 return;339 }340 341 /* switch audio */342 dev_dbg_lvl(&client->dev, 1, msp_debug, "set audmode %d\n", audmode);343 switch (audmode) {344 case V4L2_TUNER_MODE_STEREO:345 case V4L2_TUNER_MODE_LANG1_LANG2:346 src |= 0x0020;347 break;348 case V4L2_TUNER_MODE_MONO:349 if (state->mode == MSP_MODE_AM_NICAM) {350 dev_dbg_lvl(&client->dev, 1, msp_debug, "switching to AM mono\n");351 /* AM mono decoding is handled by tuner, not MSP chip */352 /* SCART switching control register */353 msp_set_scart(client, SCART_MONO, 0);354 src = 0x0200;355 break;356 }357 if (state->rxsubchans & V4L2_TUNER_SUB_STEREO)358 src = 0x0030;359 break;360 case V4L2_TUNER_MODE_LANG1:361 break;362 case V4L2_TUNER_MODE_LANG2:363 src |= 0x0010;364 break;365 }366 dev_dbg_lvl(&client->dev, 1, msp_debug,367 "set_audmode final source/matrix = 0x%x\n", src);368 369 msp_set_source(client, src);370}371 372static void msp3400c_print_mode(struct i2c_client *client)373{374 struct msp_state *state = to_state(i2c_get_clientdata(client));375 376 if (state->main == state->second)377 dev_dbg_lvl(&client->dev, 1, msp_debug,378 "mono sound carrier: %d.%03d MHz\n",379 state->main / 910000, (state->main / 910) % 1000);380 else381 dev_dbg_lvl(&client->dev, 1, msp_debug,382 "main sound carrier: %d.%03d MHz\n",383 state->main / 910000, (state->main / 910) % 1000);384 if (state->mode == MSP_MODE_FM_NICAM1 || state->mode == MSP_MODE_FM_NICAM2)385 dev_dbg_lvl(&client->dev, 1, msp_debug,386 "NICAM/FM carrier : %d.%03d MHz\n",387 state->second / 910000, (state->second/910) % 1000);388 if (state->mode == MSP_MODE_AM_NICAM)389 dev_dbg_lvl(&client->dev, 1, msp_debug,390 "NICAM/AM carrier : %d.%03d MHz\n",391 state->second / 910000, (state->second / 910) % 1000);392 if (state->mode == MSP_MODE_FM_TERRA && state->main != state->second) {393 dev_dbg_lvl(&client->dev, 1, msp_debug,394 "FM-stereo carrier : %d.%03d MHz\n",395 state->second / 910000, (state->second / 910) % 1000);396 }397}398 399/* ----------------------------------------------------------------------- */400 401static int msp3400c_detect_stereo(struct i2c_client *client)402{403 struct msp_state *state = to_state(i2c_get_clientdata(client));404 int val;405 int rxsubchans = state->rxsubchans;406 int newnicam = state->nicam_on;407 int update = 0;408 409 switch (state->mode) {410 case MSP_MODE_FM_TERRA:411 val = msp_read_dsp(client, 0x18);412 if (val > 32767)413 val -= 65536;414 dev_dbg_lvl(&client->dev, 2, msp_debug,415 "stereo detect register: %d\n", val);416 if (val > 8192) {417 rxsubchans = V4L2_TUNER_SUB_STEREO;418 } else if (val < -4096) {419 rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;420 } else {421 rxsubchans = V4L2_TUNER_SUB_MONO;422 }423 newnicam = 0;424 break;425 case MSP_MODE_FM_NICAM1:426 case MSP_MODE_FM_NICAM2:427 case MSP_MODE_AM_NICAM:428 val = msp_read_dem(client, 0x23);429 dev_dbg_lvl(&client->dev, 2, msp_debug, "nicam sync=%d, mode=%d\n",430 val & 1, (val & 0x1e) >> 1);431 432 if (val & 1) {433 /* nicam synced */434 switch ((val & 0x1e) >> 1) {435 case 0:436 case 8:437 rxsubchans = V4L2_TUNER_SUB_STEREO;438 break;439 case 1:440 case 9:441 rxsubchans = V4L2_TUNER_SUB_MONO;442 break;443 case 2:444 case 10:445 rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;446 break;447 default:448 rxsubchans = V4L2_TUNER_SUB_MONO;449 break;450 }451 newnicam = 1;452 } else {453 newnicam = 0;454 rxsubchans = V4L2_TUNER_SUB_MONO;455 }456 break;457 }458 if (rxsubchans != state->rxsubchans) {459 update = 1;460 dev_dbg_lvl(&client->dev, 1, msp_debug,461 "watch: rxsubchans %02x => %02x\n",462 state->rxsubchans, rxsubchans);463 state->rxsubchans = rxsubchans;464 }465 if (newnicam != state->nicam_on) {466 update = 1;467 dev_dbg_lvl(&client->dev, 1, msp_debug, "watch: nicam %d => %d\n",468 state->nicam_on, newnicam);469 state->nicam_on = newnicam;470 }471 return update;472}473 474/*475 * A kernel thread for msp3400 control -- we don't want to block the476 * in the ioctl while doing the sound carrier & stereo detect477 */478/* stereo/multilang monitoring */479static void watch_stereo(struct i2c_client *client)480{481 struct msp_state *state = to_state(i2c_get_clientdata(client));482 483 if (msp_detect_stereo(client))484 msp_set_audmode(client);485 486 if (msp_once)487 state->watch_stereo = 0;488}489 490int msp3400c_thread(void *data)491{492 struct i2c_client *client = data;493 struct msp_state *state = to_state(i2c_get_clientdata(client));494 struct msp3400c_carrier_detect *cd;495 int count, max1, max2, val1, val2, val, i;496 497 dev_dbg_lvl(&client->dev, 1, msp_debug, "msp3400 daemon started\n");498 state->detected_std = V4L2_STD_ALL;499 set_freezable();500 for (;;) {501 dev_dbg_lvl(&client->dev, 2, msp_debug, "msp3400 thread: sleep\n");502 msp_sleep(state, -1);503 dev_dbg_lvl(&client->dev, 2, msp_debug, "msp3400 thread: wakeup\n");504 505restart:506 dev_dbg_lvl(&client->dev, 2, msp_debug, "thread: restart scan\n");507 state->restart = 0;508 if (kthread_should_stop())509 break;510 511 if (state->radio || MSP_MODE_EXTERN == state->mode) {512 /* no carrier scan, just unmute */513 dev_dbg_lvl(&client->dev, 1, msp_debug,514 "thread: no carrier scan\n");515 state->scan_in_progress = 0;516 msp_update_volume(state);517 continue;518 }519 520 /* mute audio */521 state->scan_in_progress = 1;522 msp_update_volume(state);523 524 msp3400c_set_mode(client, MSP_MODE_AM_DETECT);525 val1 = val2 = 0;526 max1 = max2 = -1;527 state->watch_stereo = 0;528 state->nicam_on = 0;529 530 /* wait for tuner to settle down after a channel change */531 if (msp_sleep(state, 200))532 goto restart;533 534 /* carrier detect pass #1 -- main carrier */535 cd = msp3400c_carrier_detect_main;536 count = ARRAY_SIZE(msp3400c_carrier_detect_main);537 538 if (msp_amsound && (state->v4l2_std & V4L2_STD_SECAM)) {539 /* autodetect doesn't work well with AM ... */540 max1 = 3;541 count = 0;542 dev_dbg_lvl(&client->dev, 1, msp_debug, "AM sound override\n");543 }544 545 for (i = 0; i < count; i++) {546 msp3400c_set_carrier(client, cd[i].cdo, cd[i].cdo);547 if (msp_sleep(state, 100))548 goto restart;549 val = msp_read_dsp(client, 0x1b);550 if (val > 32767)551 val -= 65536;552 if (val1 < val) {553 val1 = val;554 max1 = i;555 }556 dev_dbg_lvl(&client->dev, 1, msp_debug,557 "carrier1 val: %5d / %s\n", val, cd[i].name);558 }559 560 /* carrier detect pass #2 -- second (stereo) carrier */561 switch (max1) {562 case 1: /* 5.5 */563 cd = msp3400c_carrier_detect_55;564 count = ARRAY_SIZE(msp3400c_carrier_detect_55);565 break;566 case 3: /* 6.5 */567 cd = msp3400c_carrier_detect_65;568 count = ARRAY_SIZE(msp3400c_carrier_detect_65);569 break;570 case 0: /* 4.5 */571 case 2: /* 6.0 */572 default:573 cd = NULL;574 count = 0;575 break;576 }577 578 if (msp_amsound && (state->v4l2_std & V4L2_STD_SECAM)) {579 /* autodetect doesn't work well with AM ... */580 cd = NULL;581 count = 0;582 max2 = 0;583 }584 for (i = 0; i < count; i++) {585 msp3400c_set_carrier(client, cd[i].cdo, cd[i].cdo);586 if (msp_sleep(state, 100))587 goto restart;588 val = msp_read_dsp(client, 0x1b);589 if (val > 32767)590 val -= 65536;591 if (val2 < val) {592 val2 = val;593 max2 = i;594 }595 dev_dbg_lvl(&client->dev, 1, msp_debug,596 "carrier2 val: %5d / %s\n", val, cd[i].name);597 }598 599 /* program the msp3400 according to the results */600 state->main = msp3400c_carrier_detect_main[max1].cdo;601 switch (max1) {602 case 1: /* 5.5 */603 state->detected_std = V4L2_STD_BG | V4L2_STD_PAL_H;604 if (max2 == 0) {605 /* B/G FM-stereo */606 state->second = msp3400c_carrier_detect_55[max2].cdo;607 msp3400c_set_mode(client, MSP_MODE_FM_TERRA);608 state->watch_stereo = 1;609 } else if (max2 == 1 && state->has_nicam) {610 /* B/G NICAM */611 state->second = msp3400c_carrier_detect_55[max2].cdo;612 msp3400c_set_mode(client, MSP_MODE_FM_NICAM1);613 state->nicam_on = 1;614 state->watch_stereo = 1;615 } else {616 goto no_second;617 }618 break;619 case 2: /* 6.0 */620 /* PAL I NICAM */621 state->detected_std = V4L2_STD_PAL_I;622 state->second = MSP_CARRIER(6.552);623 msp3400c_set_mode(client, MSP_MODE_FM_NICAM2);624 state->nicam_on = 1;625 state->watch_stereo = 1;626 break;627 case 3: /* 6.5 */628 if (max2 == 1 || max2 == 2) {629 /* D/K FM-stereo */630 state->second = msp3400c_carrier_detect_65[max2].cdo;631 msp3400c_set_mode(client, MSP_MODE_FM_TERRA);632 state->watch_stereo = 1;633 state->detected_std = V4L2_STD_DK;634 } else if (max2 == 0 && (state->v4l2_std & V4L2_STD_SECAM)) {635 /* L NICAM or AM-mono */636 state->second = msp3400c_carrier_detect_65[max2].cdo;637 msp3400c_set_mode(client, MSP_MODE_AM_NICAM);638 state->watch_stereo = 1;639 state->detected_std = V4L2_STD_L;640 } else if (max2 == 0 && state->has_nicam) {641 /* D/K NICAM */642 state->second = msp3400c_carrier_detect_65[max2].cdo;643 msp3400c_set_mode(client, MSP_MODE_FM_NICAM1);644 state->nicam_on = 1;645 state->watch_stereo = 1;646 state->detected_std = V4L2_STD_DK;647 } else {648 goto no_second;649 }650 break;651 case 0: /* 4.5 */652 state->detected_std = V4L2_STD_MN;653 fallthrough;654 default:655no_second:656 state->second = msp3400c_carrier_detect_main[max1].cdo;657 msp3400c_set_mode(client, MSP_MODE_FM_TERRA);658 break;659 }660 msp3400c_set_carrier(client, state->second, state->main);661 662 /* unmute */663 state->scan_in_progress = 0;664 msp3400c_set_audmode(client);665 msp_update_volume(state);666 667 if (msp_debug)668 msp3400c_print_mode(client);669 670 /* monitor tv audio mode, the first time don't wait671 so long to get a quick stereo/bilingual result */672 count = 3;673 while (state->watch_stereo) {674 if (msp_sleep(state, count ? 1000 : 5000))675 goto restart;676 if (count)677 count--;678 watch_stereo(client);679 }680 }681 dev_dbg_lvl(&client->dev, 1, msp_debug, "thread: exit\n");682 return 0;683}684 685 686int msp3410d_thread(void *data)687{688 struct i2c_client *client = data;689 struct msp_state *state = to_state(i2c_get_clientdata(client));690 int val, i, std, count;691 692 dev_dbg_lvl(&client->dev, 1, msp_debug, "msp3410 daemon started\n");693 state->detected_std = V4L2_STD_ALL;694 set_freezable();695 for (;;) {696 dev_dbg_lvl(&client->dev, 2, msp_debug, "msp3410 thread: sleep\n");697 msp_sleep(state, -1);698 dev_dbg_lvl(&client->dev, 2, msp_debug, "msp3410 thread: wakeup\n");699 700restart:701 dev_dbg_lvl(&client->dev, 2, msp_debug, "thread: restart scan\n");702 state->restart = 0;703 if (kthread_should_stop())704 break;705 706 if (state->mode == MSP_MODE_EXTERN) {707 /* no carrier scan needed, just unmute */708 dev_dbg_lvl(&client->dev, 1, msp_debug,709 "thread: no carrier scan\n");710 state->scan_in_progress = 0;711 msp_update_volume(state);712 continue;713 }714 715 /* mute audio */716 state->scan_in_progress = 1;717 msp_update_volume(state);718 719 /* start autodetect. Note: autodetect is not supported for720 NTSC-M and radio, hence we force the standard in those721 cases. */722 if (state->radio)723 std = 0x40;724 else725 std = (state->v4l2_std & V4L2_STD_NTSC) ? 0x20 : 1;726 state->watch_stereo = 0;727 state->nicam_on = 0;728 729 /* wait for tuner to settle down after a channel change */730 if (msp_sleep(state, 200))731 goto restart;732 733 if (msp_debug)734 dev_dbg_lvl(&client->dev, 2, msp_debug,735 "setting standard: %s (0x%04x)\n",736 msp_standard_std_name(std), std);737 738 if (std != 1) {739 /* programmed some specific mode */740 val = std;741 } else {742 /* triggered autodetect */743 msp_write_dem(client, 0x20, std);744 for (;;) {745 if (msp_sleep(state, 100))746 goto restart;747 748 /* check results */749 val = msp_read_dem(client, 0x7e);750 if (val < 0x07ff)751 break;752 dev_dbg_lvl(&client->dev, 2, msp_debug,753 "detection still in progress\n");754 }755 }756 for (i = 0; msp_stdlist[i].name != NULL; i++)757 if (msp_stdlist[i].retval == val)758 break;759 dev_dbg_lvl(&client->dev, 1, msp_debug, "current standard: %s (0x%04x)\n",760 msp_standard_std_name(val), val);761 state->main = msp_stdlist[i].main;762 state->second = msp_stdlist[i].second;763 state->std = val;764 state->rxsubchans = V4L2_TUNER_SUB_MONO;765 766 if (msp_amsound && !state->radio &&767 (state->v4l2_std & V4L2_STD_SECAM) && (val != 0x0009)) {768 /* autodetection has failed, let backup */769 dev_dbg_lvl(&client->dev, 1, msp_debug, "autodetection failed, switching to backup standard: %s (0x%04x)\n",770 msp_stdlist[8].name ?771 msp_stdlist[8].name : "unknown", val);772 state->std = val = 0x0009;773 msp_write_dem(client, 0x20, val);774 } else {775 state->detected_std = msp_standard_std(state->std);776 }777 778 /* set stereo */779 switch (val) {780 case 0x0008: /* B/G NICAM */781 case 0x000a: /* I NICAM */782 case 0x000b: /* D/K NICAM */783 if (val == 0x000a)784 state->mode = MSP_MODE_FM_NICAM2;785 else786 state->mode = MSP_MODE_FM_NICAM1;787 /* just turn on stereo */788 state->nicam_on = 1;789 state->watch_stereo = 1;790 break;791 case 0x0009:792 state->mode = MSP_MODE_AM_NICAM;793 state->nicam_on = 1;794 state->watch_stereo = 1;795 break;796 case 0x0020: /* BTSC */797 /* The pre-'G' models only have BTSC-mono */798 state->mode = MSP_MODE_BTSC;799 break;800 case 0x0040: /* FM radio */801 state->mode = MSP_MODE_FM_RADIO;802 state->rxsubchans = V4L2_TUNER_SUB_STEREO;803 /* not needed in theory if we have radio, but804 short programming enables carrier mute */805 msp3400c_set_mode(client, MSP_MODE_FM_RADIO);806 msp3400c_set_carrier(client, MSP_CARRIER(10.7),807 MSP_CARRIER(10.7));808 break;809 case 0x0002:810 case 0x0003:811 case 0x0004:812 case 0x0005:813 state->mode = MSP_MODE_FM_TERRA;814 state->watch_stereo = 1;815 break;816 }817 818 /* set various prescales */819 msp_write_dsp(client, 0x0d, 0x1900); /* scart */820 msp_write_dsp(client, 0x0e, 0x3000); /* FM */821 if (state->has_nicam)822 msp_write_dsp(client, 0x10, 0x5a00); /* nicam */823 824 if (state->has_i2s_conf)825 msp_write_dem(client, 0x40, state->i2s_mode);826 827 /* unmute */828 msp3400c_set_audmode(client);829 state->scan_in_progress = 0;830 msp_update_volume(state);831 832 /* monitor tv audio mode, the first time don't wait833 so long to get a quick stereo/bilingual result */834 count = 3;835 while (state->watch_stereo) {836 if (msp_sleep(state, count ? 1000 : 5000))837 goto restart;838 if (count)839 count--;840 watch_stereo(client);841 }842 }843 dev_dbg_lvl(&client->dev, 1, msp_debug, "thread: exit\n");844 return 0;845}846 847/* ----------------------------------------------------------------------- */848 849/* msp34xxG + (autoselect no-thread)850 * this one uses both automatic standard detection and automatic sound851 * select which are available in the newer G versions852 * struct msp: only norm, acb and source are really used in this mode853 */854 855static int msp34xxg_modus(struct i2c_client *client)856{857 struct msp_state *state = to_state(i2c_get_clientdata(client));858 859 if (state->radio) {860 dev_dbg_lvl(&client->dev, 1, msp_debug, "selected radio modus\n");861 return 0x0001;862 }863 if (state->v4l2_std == V4L2_STD_NTSC_M_JP) {864 dev_dbg_lvl(&client->dev, 1, msp_debug, "selected M (EIA-J) modus\n");865 return 0x4001;866 }867 if (state->v4l2_std == V4L2_STD_NTSC_M_KR) {868 dev_dbg_lvl(&client->dev, 1, msp_debug, "selected M (A2) modus\n");869 return 0x0001;870 }871 if (state->v4l2_std == V4L2_STD_SECAM_L) {872 dev_dbg_lvl(&client->dev, 1, msp_debug, "selected SECAM-L modus\n");873 return 0x6001;874 }875 if (state->v4l2_std & V4L2_STD_MN) {876 dev_dbg_lvl(&client->dev, 1, msp_debug, "selected M (BTSC) modus\n");877 return 0x2001;878 }879 return 0x7001;880}881 882static void msp34xxg_set_source(struct i2c_client *client, u16 reg, int in)883{884 struct msp_state *state = to_state(i2c_get_clientdata(client));885 int source, matrix;886 887 switch (state->audmode) {888 case V4L2_TUNER_MODE_MONO:889 source = 0; /* mono only */890 matrix = 0x30;891 break;892 case V4L2_TUNER_MODE_LANG2:893 source = 4; /* stereo or B */894 matrix = 0x10;895 break;896 case V4L2_TUNER_MODE_LANG1_LANG2:897 source = 1; /* stereo or A|B */898 matrix = 0x20;899 break;900 case V4L2_TUNER_MODE_LANG1:901 source = 3; /* stereo or A */902 matrix = 0x00;903 break;904 case V4L2_TUNER_MODE_STEREO:905 default:906 source = 3; /* stereo or A */907 matrix = 0x20;908 break;909 }910 911 if (in == MSP_DSP_IN_TUNER)912 source = (source << 8) | 0x20;913 /* the msp34x2g puts the MAIN_AVC, MAIN and AUX sources in 12, 13, 14914 instead of 11, 12, 13. So we add one for that msp version. */915 else if (in >= MSP_DSP_IN_MAIN_AVC && state->has_dolby_pro_logic)916 source = ((in + 1) << 8) | matrix;917 else918 source = (in << 8) | matrix;919 920 dev_dbg_lvl(&client->dev, 1, msp_debug,921 "set source to %d (0x%x) for output %02x\n", in, source, reg);922 msp_write_dsp(client, reg, source);923}924 925static void msp34xxg_set_sources(struct i2c_client *client)926{927 struct msp_state *state = to_state(i2c_get_clientdata(client));928 u32 in = state->route_in;929 930 msp34xxg_set_source(client, 0x0008, (in >> 4) & 0xf);931 /* quasi-peak detector is set to same input as the loudspeaker (MAIN) */932 msp34xxg_set_source(client, 0x000c, (in >> 4) & 0xf);933 msp34xxg_set_source(client, 0x0009, (in >> 8) & 0xf);934 msp34xxg_set_source(client, 0x000a, (in >> 12) & 0xf);935 if (state->has_scart2_out)936 msp34xxg_set_source(client, 0x0041, (in >> 16) & 0xf);937 msp34xxg_set_source(client, 0x000b, (in >> 20) & 0xf);938}939 940/* (re-)initialize the msp34xxg */941static void msp34xxg_reset(struct i2c_client *client)942{943 struct msp_state *state = to_state(i2c_get_clientdata(client));944 int tuner = (state->route_in >> 3) & 1;945 int modus;946 947 /* initialize std to 1 (autodetect) to signal that no standard is948 selected yet. */949 state->std = 1;950 951 msp_reset(client);952 953 if (state->has_i2s_conf)954 msp_write_dem(client, 0x40, state->i2s_mode);955 956 /* step-by-step initialisation, as described in the manual */957 modus = msp34xxg_modus(client);958 modus |= tuner ? 0x100 : 0;959 msp_write_dem(client, 0x30, modus);960 961 /* write the dsps that may have an influence on962 standard/audio autodetection right now */963 msp34xxg_set_sources(client);964 965 msp_write_dsp(client, 0x0d, 0x1900); /* scart */966 msp_write_dsp(client, 0x0e, 0x3000); /* FM */967 if (state->has_nicam)968 msp_write_dsp(client, 0x10, 0x5a00); /* nicam */969 970 /* set identification threshold. Personally, I971 * I set it to a higher value than the default972 * of 0x190 to ignore noisy stereo signals.973 * this needs tuning. (recommended range 0x00a0-0x03c0)974 * 0x7f0 = forced mono mode975 *976 * a2 threshold for stereo/bilingual.977 * Note: this register is part of the Manual/Compatibility mode.978 * It is supported by all 'G'-family chips.979 */980 msp_write_dem(client, 0x22, msp_stereo_thresh);981}982 983int msp34xxg_thread(void *data)984{985 struct i2c_client *client = data;986 struct msp_state *state = to_state(i2c_get_clientdata(client));987 int val, i;988 989 dev_dbg_lvl(&client->dev, 1, msp_debug, "msp34xxg daemon started\n");990 state->detected_std = V4L2_STD_ALL;991 set_freezable();992 for (;;) {993 dev_dbg_lvl(&client->dev, 2, msp_debug, "msp34xxg thread: sleep\n");994 msp_sleep(state, -1);995 dev_dbg_lvl(&client->dev, 2, msp_debug, "msp34xxg thread: wakeup\n");996 997restart:998 dev_dbg_lvl(&client->dev, 1, msp_debug, "thread: restart scan\n");999 state->restart = 0;1000 if (kthread_should_stop())1001 break;1002 1003 if (state->mode == MSP_MODE_EXTERN) {1004 /* no carrier scan needed, just unmute */1005 dev_dbg_lvl(&client->dev, 1, msp_debug,1006 "thread: no carrier scan\n");1007 state->scan_in_progress = 0;1008 msp_update_volume(state);1009 continue;1010 }1011 1012 /* setup the chip*/1013 msp34xxg_reset(client);1014 state->std = state->radio ? 0x40 :1015 (state->force_btsc && msp_standard == 1) ? 32 : msp_standard;1016 msp_write_dem(client, 0x20, state->std);1017 /* start autodetect */1018 if (state->std != 1)1019 goto unmute;1020 1021 /* watch autodetect */1022 dev_dbg_lvl(&client->dev, 1, msp_debug,1023 "started autodetect, waiting for result\n");1024 for (i = 0; i < 10; i++) {1025 if (msp_sleep(state, 100))1026 goto restart;1027 1028 /* check results */1029 val = msp_read_dem(client, 0x7e);1030 if (val < 0x07ff) {1031 state->std = val;1032 break;1033 }1034 dev_dbg_lvl(&client->dev, 2, msp_debug,1035 "detection still in progress\n");1036 }1037 if (state->std == 1) {1038 dev_dbg_lvl(&client->dev, 1, msp_debug,1039 "detection still in progress after 10 tries. giving up.\n");1040 continue;1041 }1042 1043unmute:1044 dev_dbg_lvl(&client->dev, 1, msp_debug,1045 "detected standard: %s (0x%04x)\n",1046 msp_standard_std_name(state->std), state->std);1047 state->detected_std = msp_standard_std(state->std);1048 1049 if (state->std == 9) {1050 /* AM NICAM mode */1051 msp_write_dsp(client, 0x0e, 0x7c00);1052 }1053 1054 /* unmute: dispatch sound to scart output, set scart volume */1055 msp_update_volume(state);1056 1057 /* restore ACB */1058 if (msp_write_dsp(client, 0x13, state->acb))1059 return -1;1060 1061 /* the periodic stereo/SAP check is only relevant for1062 the 0x20 standard (BTSC) */1063 if (state->std != 0x20)1064 continue;1065 1066 state->watch_stereo = 1;1067 1068 /* monitor tv audio mode, the first time don't wait1069 in order to get a quick stereo/SAP update */1070 watch_stereo(client);1071 while (state->watch_stereo) {1072 watch_stereo(client);1073 if (msp_sleep(state, 5000))1074 goto restart;1075 }1076 }1077 dev_dbg_lvl(&client->dev, 1, msp_debug, "thread: exit\n");1078 return 0;1079}1080 1081static int msp34xxg_detect_stereo(struct i2c_client *client)1082{1083 struct msp_state *state = to_state(i2c_get_clientdata(client));1084 int status = msp_read_dem(client, 0x0200);1085 int is_bilingual = status & 0x100;1086 int is_stereo = status & 0x40;1087 int oldrx = state->rxsubchans;1088 1089 if (state->mode == MSP_MODE_EXTERN)1090 return 0;1091 1092 state->rxsubchans = 0;1093 if (is_stereo)1094 state->rxsubchans = V4L2_TUNER_SUB_STEREO;1095 else1096 state->rxsubchans = V4L2_TUNER_SUB_MONO;1097 if (is_bilingual) {1098 if (state->std == 0x20)1099 state->rxsubchans |= V4L2_TUNER_SUB_SAP;1100 else1101 state->rxsubchans =1102 V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;1103 }1104 dev_dbg_lvl(&client->dev, 1, msp_debug,1105 "status=0x%x, stereo=%d, bilingual=%d -> rxsubchans=%d\n",1106 status, is_stereo, is_bilingual, state->rxsubchans);1107 return (oldrx != state->rxsubchans);1108}1109 1110static void msp34xxg_set_audmode(struct i2c_client *client)1111{1112 struct msp_state *state = to_state(i2c_get_clientdata(client));1113 1114 if (state->std == 0x20) {1115 if ((state->rxsubchans & V4L2_TUNER_SUB_SAP) &&1116 (state->audmode == V4L2_TUNER_MODE_LANG1_LANG2 ||1117 state->audmode == V4L2_TUNER_MODE_LANG2)) {1118 msp_write_dem(client, 0x20, 0x21);1119 } else {1120 msp_write_dem(client, 0x20, 0x20);1121 }1122 }1123 1124 msp34xxg_set_sources(client);1125}1126 1127void msp_set_audmode(struct i2c_client *client)1128{1129 struct msp_state *state = to_state(i2c_get_clientdata(client));1130 1131 switch (state->opmode) {1132 case OPMODE_MANUAL:1133 case OPMODE_AUTODETECT:1134 msp3400c_set_audmode(client);1135 break;1136 case OPMODE_AUTOSELECT:1137 msp34xxg_set_audmode(client);1138 break;1139 }1140}1141 1142int msp_detect_stereo(struct i2c_client *client)1143{1144 struct msp_state *state = to_state(i2c_get_clientdata(client));1145 1146 switch (state->opmode) {1147 case OPMODE_MANUAL:1148 case OPMODE_AUTODETECT:1149 return msp3400c_detect_stereo(client);1150 case OPMODE_AUTOSELECT:1151 return msp34xxg_detect_stereo(client);1152 }1153 return 0;1154}1155 1156