cs42l42.c (585e7079de0eac555bcdfe6284e439ee05fb18cb) cs42l42.c (c5b8ee0879bcdc5082d42fe92d3c235b74feef37)
1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * cs42l42.c -- CS42L42 ALSA SoC audio driver
4 *
5 * Copyright 2016 Cirrus Logic, Inc.
6 *
7 * Author: James Schulman <james.schulman@cirrus.com>
8 * Author: Brian Austin <brian.austin@cirrus.com>

--- 508 unchanged lines hidden (view full) ---

517 { "SDOUT1", NULL, "ASP TX EN" },
518 { "SDOUT2", NULL, "ASP TX EN" },
519};
520
521static int cs42l42_component_probe(struct snd_soc_component *component)
522{
523 struct cs42l42_private *cs42l42 =
524 (struct cs42l42_private *)snd_soc_component_get_drvdata(component);
1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * cs42l42.c -- CS42L42 ALSA SoC audio driver
4 *
5 * Copyright 2016 Cirrus Logic, Inc.
6 *
7 * Author: James Schulman <james.schulman@cirrus.com>
8 * Author: Brian Austin <brian.austin@cirrus.com>

--- 508 unchanged lines hidden (view full) ---

517 { "SDOUT1", NULL, "ASP TX EN" },
518 { "SDOUT2", NULL, "ASP TX EN" },
519};
520
521static int cs42l42_component_probe(struct snd_soc_component *component)
522{
523 struct cs42l42_private *cs42l42 =
524 (struct cs42l42_private *)snd_soc_component_get_drvdata(component);
525 struct snd_soc_card *crd = component->card;
526 int ret = 0;
525
526 cs42l42->component = component;
527
527
528 cs42l42->component = component;
529
528 return 0;
530 ret = snd_soc_card_jack_new(crd, "CS42L42 Headset", SND_JACK_HEADSET | SND_JACK_BTN_0 |
531 SND_JACK_BTN_1 | SND_JACK_BTN_2 | SND_JACK_BTN_3,
532 &cs42l42->jack, NULL, 0);
533 if (ret < 0)
534 dev_err(component->dev, "Cannot create CS42L42 Headset: %d\n", ret);
535
536 return ret;
529}
530
531static const struct snd_soc_component_driver soc_component_dev_cs42l42 = {
532 .probe = cs42l42_component_probe,
533 .dapm_widgets = cs42l42_dapm_widgets,
534 .num_dapm_widgets = ARRAY_SIZE(cs42l42_dapm_widgets),
535 .dapm_routes = cs42l42_audio_map,
536 .num_dapm_routes = ARRAY_SIZE(cs42l42_audio_map),

--- 656 unchanged lines hidden (view full) ---

1193 CS42L42_HSBIAS_REF_MASK |
1194 CS42L42_HSDET_AUTO_TIME_MASK,
1195 (0 << CS42L42_HSDET_CTRL_SHIFT) |
1196 (2 << CS42L42_HSDET_SET_SHIFT) |
1197 (0 << CS42L42_HSBIAS_REF_SHIFT) |
1198 (3 << CS42L42_HSDET_AUTO_TIME_SHIFT));
1199}
1200
537}
538
539static const struct snd_soc_component_driver soc_component_dev_cs42l42 = {
540 .probe = cs42l42_component_probe,
541 .dapm_widgets = cs42l42_dapm_widgets,
542 .num_dapm_widgets = ARRAY_SIZE(cs42l42_dapm_widgets),
543 .dapm_routes = cs42l42_audio_map,
544 .num_dapm_routes = ARRAY_SIZE(cs42l42_audio_map),

--- 656 unchanged lines hidden (view full) ---

1201 CS42L42_HSBIAS_REF_MASK |
1202 CS42L42_HSDET_AUTO_TIME_MASK,
1203 (0 << CS42L42_HSDET_CTRL_SHIFT) |
1204 (2 << CS42L42_HSDET_SET_SHIFT) |
1205 (0 << CS42L42_HSBIAS_REF_SHIFT) |
1206 (3 << CS42L42_HSDET_AUTO_TIME_SHIFT));
1207}
1208
1201static void cs42l42_handle_button_press(struct cs42l42_private *cs42l42)
1209static int cs42l42_handle_button_press(struct cs42l42_private *cs42l42)
1202{
1203 int bias_level;
1204 unsigned int detect_status;
1205
1206 /* Mask button detect interrupts */
1207 regmap_update_bits(cs42l42->regmap,
1208 CS42L42_DET_INT2_MASK,
1209 CS42L42_M_DETECT_TF_MASK |

--- 26 unchanged lines hidden (view full) ---

1236
1237 regmap_read(cs42l42->regmap, CS42L42_DET_STATUS2,
1238 &detect_status);
1239 } while ((detect_status & CS42L42_HS_TRUE_MASK) &&
1240 (++bias_level < CS42L42_NUM_BIASES));
1241
1242 switch (bias_level) {
1243 case 1: /* Function C button press */
1210{
1211 int bias_level;
1212 unsigned int detect_status;
1213
1214 /* Mask button detect interrupts */
1215 regmap_update_bits(cs42l42->regmap,
1216 CS42L42_DET_INT2_MASK,
1217 CS42L42_M_DETECT_TF_MASK |

--- 26 unchanged lines hidden (view full) ---

1244
1245 regmap_read(cs42l42->regmap, CS42L42_DET_STATUS2,
1246 &detect_status);
1247 } while ((detect_status & CS42L42_HS_TRUE_MASK) &&
1248 (++bias_level < CS42L42_NUM_BIASES));
1249
1250 switch (bias_level) {
1251 case 1: /* Function C button press */
1252 bias_level = SND_JACK_BTN_2;
1244 dev_dbg(cs42l42->component->dev, "Function C button press\n");
1245 break;
1246 case 2: /* Function B button press */
1253 dev_dbg(cs42l42->component->dev, "Function C button press\n");
1254 break;
1255 case 2: /* Function B button press */
1256 bias_level = SND_JACK_BTN_1;
1247 dev_dbg(cs42l42->component->dev, "Function B button press\n");
1248 break;
1249 case 3: /* Function D button press */
1257 dev_dbg(cs42l42->component->dev, "Function B button press\n");
1258 break;
1259 case 3: /* Function D button press */
1260 bias_level = SND_JACK_BTN_3;
1250 dev_dbg(cs42l42->component->dev, "Function D button press\n");
1251 break;
1252 case 4: /* Function A button press */
1261 dev_dbg(cs42l42->component->dev, "Function D button press\n");
1262 break;
1263 case 4: /* Function A button press */
1264 bias_level = SND_JACK_BTN_0;
1253 dev_dbg(cs42l42->component->dev, "Function A button press\n");
1254 break;
1265 dev_dbg(cs42l42->component->dev, "Function A button press\n");
1266 break;
1267 default:
1268 bias_level = 0;
1269 break;
1255 }
1256
1257 /* Set button detect level sensitivity back to default */
1258 regmap_update_bits(cs42l42->regmap,
1259 CS42L42_MIC_DET_CTL1,
1260 CS42L42_LATCH_TO_VP_MASK |
1261 CS42L42_EVENT_STAT_SEL_MASK |
1262 CS42L42_HS_DET_LEVEL_MASK,

--- 13 unchanged lines hidden (view full) ---

1276 CS42L42_M_HSBIAS_HIZ_MASK |
1277 CS42L42_M_SHORT_RLS_MASK |
1278 CS42L42_M_SHORT_DET_MASK,
1279 (0 << CS42L42_M_DETECT_TF_SHIFT) |
1280 (0 << CS42L42_M_DETECT_FT_SHIFT) |
1281 (0 << CS42L42_M_HSBIAS_HIZ_SHIFT) |
1282 (1 << CS42L42_M_SHORT_RLS_SHIFT) |
1283 (1 << CS42L42_M_SHORT_DET_SHIFT));
1270 }
1271
1272 /* Set button detect level sensitivity back to default */
1273 regmap_update_bits(cs42l42->regmap,
1274 CS42L42_MIC_DET_CTL1,
1275 CS42L42_LATCH_TO_VP_MASK |
1276 CS42L42_EVENT_STAT_SEL_MASK |
1277 CS42L42_HS_DET_LEVEL_MASK,

--- 13 unchanged lines hidden (view full) ---

1291 CS42L42_M_HSBIAS_HIZ_MASK |
1292 CS42L42_M_SHORT_RLS_MASK |
1293 CS42L42_M_SHORT_DET_MASK,
1294 (0 << CS42L42_M_DETECT_TF_SHIFT) |
1295 (0 << CS42L42_M_DETECT_FT_SHIFT) |
1296 (0 << CS42L42_M_HSBIAS_HIZ_SHIFT) |
1297 (1 << CS42L42_M_SHORT_RLS_SHIFT) |
1298 (1 << CS42L42_M_SHORT_DET_SHIFT));
1299
1300 return bias_level;
1284}
1285
1286struct cs42l42_irq_params {
1287 u16 status_addr;
1288 u16 mask_addr;
1289 u8 mask;
1290};
1291

--- 28 unchanged lines hidden (view full) ---

1320{
1321 struct cs42l42_private *cs42l42 = (struct cs42l42_private *)data;
1322 struct snd_soc_component *component = cs42l42->component;
1323 unsigned int stickies[12];
1324 unsigned int masks[12];
1325 unsigned int current_plug_status;
1326 unsigned int current_button_status;
1327 unsigned int i;
1301}
1302
1303struct cs42l42_irq_params {
1304 u16 status_addr;
1305 u16 mask_addr;
1306 u8 mask;
1307};
1308

--- 28 unchanged lines hidden (view full) ---

1337{
1338 struct cs42l42_private *cs42l42 = (struct cs42l42_private *)data;
1339 struct snd_soc_component *component = cs42l42->component;
1340 unsigned int stickies[12];
1341 unsigned int masks[12];
1342 unsigned int current_plug_status;
1343 unsigned int current_button_status;
1344 unsigned int i;
1345 int report = 0;
1328
1346
1347
1329 /* Read sticky registers to clear interurpt */
1330 for (i = 0; i < ARRAY_SIZE(stickies); i++) {
1331 regmap_read(cs42l42->regmap, irq_params_table[i].status_addr,
1332 &(stickies[i]));
1333 regmap_read(cs42l42->regmap, irq_params_table[i].mask_addr,
1334 &(masks[i]));
1335 stickies[i] = stickies[i] & (~masks[i]) &
1336 irq_params_table[i].mask;

--- 9 unchanged lines hidden (view full) ---

1346 (CS42L42_M_DETECT_TF_MASK |
1347 CS42L42_M_DETECT_FT_MASK |
1348 CS42L42_M_HSBIAS_HIZ_MASK);
1349
1350 /* Check auto-detect status */
1351 if ((~masks[5]) & irq_params_table[5].mask) {
1352 if (stickies[5] & CS42L42_HSDET_AUTO_DONE_MASK) {
1353 cs42l42_process_hs_type_detect(cs42l42);
1348 /* Read sticky registers to clear interurpt */
1349 for (i = 0; i < ARRAY_SIZE(stickies); i++) {
1350 regmap_read(cs42l42->regmap, irq_params_table[i].status_addr,
1351 &(stickies[i]));
1352 regmap_read(cs42l42->regmap, irq_params_table[i].mask_addr,
1353 &(masks[i]));
1354 stickies[i] = stickies[i] & (~masks[i]) &
1355 irq_params_table[i].mask;

--- 9 unchanged lines hidden (view full) ---

1365 (CS42L42_M_DETECT_TF_MASK |
1366 CS42L42_M_DETECT_FT_MASK |
1367 CS42L42_M_HSBIAS_HIZ_MASK);
1368
1369 /* Check auto-detect status */
1370 if ((~masks[5]) & irq_params_table[5].mask) {
1371 if (stickies[5] & CS42L42_HSDET_AUTO_DONE_MASK) {
1372 cs42l42_process_hs_type_detect(cs42l42);
1354 dev_dbg(component->dev,
1355 "Auto detect done (%d)\n",
1356 cs42l42->hs_type);
1373 switch(cs42l42->hs_type){
1374 case CS42L42_PLUG_CTIA:
1375 case CS42L42_PLUG_OMTP:
1376 snd_soc_jack_report(&cs42l42->jack, SND_JACK_HEADSET,
1377 SND_JACK_HEADSET);
1378 break;
1379 case CS42L42_PLUG_HEADPHONE:
1380 snd_soc_jack_report(&cs42l42->jack, SND_JACK_HEADPHONE,
1381 SND_JACK_HEADPHONE);
1382 break;
1383 default:
1384 break;
1385 }
1386 dev_dbg(component->dev, "Auto detect done (%d)\n", cs42l42->hs_type);
1357 }
1358 }
1359
1360 /* Check tip sense status */
1361 if ((~masks[11]) & irq_params_table[11].mask) {
1362 switch (current_plug_status) {
1363 case CS42L42_TS_PLUG:
1364 if (cs42l42->plug_state != CS42L42_TS_PLUG) {
1365 cs42l42->plug_state = CS42L42_TS_PLUG;
1366 cs42l42_init_hs_type_detect(cs42l42);
1367 }
1368 break;
1369
1370 case CS42L42_TS_UNPLUG:
1371 if (cs42l42->plug_state != CS42L42_TS_UNPLUG) {
1372 cs42l42->plug_state = CS42L42_TS_UNPLUG;
1373 cs42l42_cancel_hs_type_detect(cs42l42);
1387 }
1388 }
1389
1390 /* Check tip sense status */
1391 if ((~masks[11]) & irq_params_table[11].mask) {
1392 switch (current_plug_status) {
1393 case CS42L42_TS_PLUG:
1394 if (cs42l42->plug_state != CS42L42_TS_PLUG) {
1395 cs42l42->plug_state = CS42L42_TS_PLUG;
1396 cs42l42_init_hs_type_detect(cs42l42);
1397 }
1398 break;
1399
1400 case CS42L42_TS_UNPLUG:
1401 if (cs42l42->plug_state != CS42L42_TS_UNPLUG) {
1402 cs42l42->plug_state = CS42L42_TS_UNPLUG;
1403 cs42l42_cancel_hs_type_detect(cs42l42);
1374 dev_dbg(component->dev,
1375 "Unplug event\n");
1404
1405 switch(cs42l42->hs_type){
1406 case CS42L42_PLUG_CTIA:
1407 case CS42L42_PLUG_OMTP:
1408 snd_soc_jack_report(&cs42l42->jack, 0, SND_JACK_HEADSET);
1409 break;
1410 case CS42L42_PLUG_HEADPHONE:
1411 snd_soc_jack_report(&cs42l42->jack, 0, SND_JACK_HEADPHONE);
1412 break;
1413 default:
1414 break;
1415 }
1416 dev_dbg(component->dev, "Unplug event\n");
1376 }
1377 break;
1378
1379 default:
1380 if (cs42l42->plug_state != CS42L42_TS_TRANS)
1381 cs42l42->plug_state = CS42L42_TS_TRANS;
1382 }
1383 }
1384
1385 /* Check button detect status */
1386 if ((~masks[7]) & irq_params_table[7].mask) {
1387 if (!(current_button_status &
1388 CS42L42_M_HSBIAS_HIZ_MASK)) {
1389
1417 }
1418 break;
1419
1420 default:
1421 if (cs42l42->plug_state != CS42L42_TS_TRANS)
1422 cs42l42->plug_state = CS42L42_TS_TRANS;
1423 }
1424 }
1425
1426 /* Check button detect status */
1427 if ((~masks[7]) & irq_params_table[7].mask) {
1428 if (!(current_button_status &
1429 CS42L42_M_HSBIAS_HIZ_MASK)) {
1430
1390 if (current_button_status &
1391 CS42L42_M_DETECT_TF_MASK) {
1392 dev_dbg(component->dev,
1393 "Button released\n");
1394 } else if (current_button_status &
1395 CS42L42_M_DETECT_FT_MASK) {
1396 cs42l42_handle_button_press(cs42l42);
1431 if (current_button_status & CS42L42_M_DETECT_TF_MASK) {
1432 dev_dbg(component->dev, "Button released\n");
1433 report = 0;
1434 } else if (current_button_status & CS42L42_M_DETECT_FT_MASK) {
1435 report = cs42l42_handle_button_press(cs42l42);
1436
1397 }
1437 }
1438 snd_soc_jack_report(&cs42l42->jack, report, SND_JACK_BTN_0 | SND_JACK_BTN_1 |
1439 SND_JACK_BTN_2 | SND_JACK_BTN_3);
1398 }
1399 }
1400
1401 return IRQ_HANDLED;
1402}
1403
1404static void cs42l42_set_interrupt_masks(struct cs42l42_private *cs42l42)
1405{

--- 556 unchanged lines hidden ---
1440 }
1441 }
1442
1443 return IRQ_HANDLED;
1444}
1445
1446static void cs42l42_set_interrupt_masks(struct cs42l42_private *cs42l42)
1447{

--- 556 unchanged lines hidden ---