{
struct cs42l42_private *cs42l42 =
(struct cs42l42_private *)snd_soc_component_get_drvdata(component);
+ struct snd_soc_card *crd = component->card;
+ int ret = 0;
cs42l42->component = component;
- return 0;
+ ret = snd_soc_card_jack_new(crd, "CS42L42 Headset", SND_JACK_HEADSET | SND_JACK_BTN_0 |
+ SND_JACK_BTN_1 | SND_JACK_BTN_2 | SND_JACK_BTN_3,
+ &cs42l42->jack, NULL, 0);
+ if (ret < 0)
+ dev_err(component->dev, "Cannot create CS42L42 Headset: %d\n", ret);
+
+ return ret;
}
static const struct snd_soc_component_driver soc_component_dev_cs42l42 = {
(3 << CS42L42_HSDET_AUTO_TIME_SHIFT));
}
-static void cs42l42_handle_button_press(struct cs42l42_private *cs42l42)
+static int cs42l42_handle_button_press(struct cs42l42_private *cs42l42)
{
int bias_level;
unsigned int detect_status;
switch (bias_level) {
case 1: /* Function C button press */
+ bias_level = SND_JACK_BTN_2;
dev_dbg(cs42l42->component->dev, "Function C button press\n");
break;
case 2: /* Function B button press */
+ bias_level = SND_JACK_BTN_1;
dev_dbg(cs42l42->component->dev, "Function B button press\n");
break;
case 3: /* Function D button press */
+ bias_level = SND_JACK_BTN_3;
dev_dbg(cs42l42->component->dev, "Function D button press\n");
break;
case 4: /* Function A button press */
+ bias_level = SND_JACK_BTN_0;
dev_dbg(cs42l42->component->dev, "Function A button press\n");
break;
+ default:
+ bias_level = 0;
+ break;
}
/* Set button detect level sensitivity back to default */
(0 << CS42L42_M_HSBIAS_HIZ_SHIFT) |
(1 << CS42L42_M_SHORT_RLS_SHIFT) |
(1 << CS42L42_M_SHORT_DET_SHIFT));
+
+ return bias_level;
}
struct cs42l42_irq_params {
unsigned int current_plug_status;
unsigned int current_button_status;
unsigned int i;
+ int report = 0;
+
/* Read sticky registers to clear interurpt */
for (i = 0; i < ARRAY_SIZE(stickies); i++) {
if ((~masks[5]) & irq_params_table[5].mask) {
if (stickies[5] & CS42L42_HSDET_AUTO_DONE_MASK) {
cs42l42_process_hs_type_detect(cs42l42);
- dev_dbg(component->dev,
- "Auto detect done (%d)\n",
- cs42l42->hs_type);
+ switch(cs42l42->hs_type){
+ case CS42L42_PLUG_CTIA:
+ case CS42L42_PLUG_OMTP:
+ snd_soc_jack_report(&cs42l42->jack, SND_JACK_HEADSET,
+ SND_JACK_HEADSET);
+ break;
+ case CS42L42_PLUG_HEADPHONE:
+ snd_soc_jack_report(&cs42l42->jack, SND_JACK_HEADPHONE,
+ SND_JACK_HEADPHONE);
+ break;
+ default:
+ break;
+ }
+ dev_dbg(component->dev, "Auto detect done (%d)\n", cs42l42->hs_type);
}
}
if (cs42l42->plug_state != CS42L42_TS_UNPLUG) {
cs42l42->plug_state = CS42L42_TS_UNPLUG;
cs42l42_cancel_hs_type_detect(cs42l42);
- dev_dbg(component->dev,
- "Unplug event\n");
+
+ switch(cs42l42->hs_type){
+ case CS42L42_PLUG_CTIA:
+ case CS42L42_PLUG_OMTP:
+ snd_soc_jack_report(&cs42l42->jack, 0, SND_JACK_HEADSET);
+ break;
+ case CS42L42_PLUG_HEADPHONE:
+ snd_soc_jack_report(&cs42l42->jack, 0, SND_JACK_HEADPHONE);
+ break;
+ default:
+ break;
+ }
+ dev_dbg(component->dev, "Unplug event\n");
}
break;
if (!(current_button_status &
CS42L42_M_HSBIAS_HIZ_MASK)) {
- if (current_button_status &
- CS42L42_M_DETECT_TF_MASK) {
- dev_dbg(component->dev,
- "Button released\n");
- } else if (current_button_status &
- CS42L42_M_DETECT_FT_MASK) {
- cs42l42_handle_button_press(cs42l42);
+ if (current_button_status & CS42L42_M_DETECT_TF_MASK) {
+ dev_dbg(component->dev, "Button released\n");
+ report = 0;
+ } else if (current_button_status & CS42L42_M_DETECT_FT_MASK) {
+ report = cs42l42_handle_button_press(cs42l42);
+
}
+ snd_soc_jack_report(&cs42l42->jack, report, SND_JACK_BTN_0 | SND_JACK_BTN_1 |
+ SND_JACK_BTN_2 | SND_JACK_BTN_3);
}
}