summaryrefslogtreecommitdiff
path: root/drivers/staging/intel_sst/intelmid_v0_control.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging/intel_sst/intelmid_v0_control.c')
-rw-r--r--drivers/staging/intel_sst/intelmid_v0_control.c109
1 files changed, 101 insertions, 8 deletions
diff --git a/drivers/staging/intel_sst/intelmid_v0_control.c b/drivers/staging/intel_sst/intelmid_v0_control.c
index 7756f8feaf85..b8dfdb9bc1aa 100644
--- a/drivers/staging/intel_sst/intelmid_v0_control.c
+++ b/drivers/staging/intel_sst/intelmid_v0_control.c
@@ -30,9 +30,10 @@
#include <linux/pci.h>
#include <linux/file.h>
+#include <sound/control.h>
#include "intel_sst.h"
#include "intelmid_snd_control.h"
-
+#include "intelmid.h"
enum _reg_v1 {
VOICEPORT1 = 0x180,
@@ -64,6 +65,7 @@ enum _reg_v1 {
};
int rev_id = 0x20;
+static bool jack_det_enabled;
/****
* fs_init_card - initialize the sound card
@@ -157,7 +159,7 @@ static int fs_power_up_pb(unsigned int port)
return fs_enable_audiodac(UNMUTE);
}
-static int fs_power_down_pb(void)
+static int fs_power_down_pb(unsigned int device)
{
struct sc_reg_access sc_access[] = {
{POWERCTRL1, 0x00, 0xC6},
@@ -195,7 +197,7 @@ static int fs_power_up_cp(unsigned int port)
return sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 2);
}
-static int fs_power_down_cp(void)
+static int fs_power_down_cp(unsigned int device)
{
struct sc_reg_access sc_access[] = {
{POWERCTRL2, 0x00, 0x03},
@@ -753,6 +755,90 @@ static int fs_get_vol(int dev_id, int *value)
return retval;
}
+static void fs_pmic_irq_enable(void *data)
+{
+ struct snd_intelmad *intelmaddata = data;
+ struct sc_reg_access sc_access[] = {
+ {0x187, 0x00, MASK7},
+ {0x188, 0x10, MASK4},
+ {0x18b, 0x10, MASK4},
+ };
+
+ struct sc_reg_access sc_access_write[] = {
+ {0x198, 0x00, 0x0},
+ };
+ pr_debug("Audio interrupt enable\n");
+ sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 3);
+ sst_sc_reg_access(sc_access_write, PMIC_WRITE, 1);
+
+ intelmaddata->jack[0].jack_status = 0;
+ /*intelmaddata->jack[1].jack_status = 0;*/
+
+ jack_det_enabled = true;
+ return;
+}
+
+static void fs_pmic_irq_cb(void *cb_data, u8 value)
+{
+ struct mad_jack *mjack = NULL;
+ struct snd_intelmad *intelmaddata = cb_data;
+ unsigned int present = 0, jack_event_flag = 0, buttonpressflag = 0;
+
+ mjack = &intelmaddata->jack[0];
+
+ if (value & 0x4) {
+ if (!jack_det_enabled)
+ fs_pmic_irq_enable(intelmaddata);
+
+ /* send headphone detect */
+ pr_debug(":MAD headphone %d\n", value & 0x4);
+ present = !(mjack->jack_status);
+ mjack->jack_status = present;
+ jack_event_flag = 1;
+ mjack->jack.type = SND_JACK_HEADPHONE;
+ }
+
+ if (value & 0x2) {
+ /* send short push */
+ pr_debug(":MAD short push %d\n", value & 0x2);
+ present = 1;
+ jack_event_flag = 1;
+ buttonpressflag = 1;
+ mjack->jack.type = MID_JACK_HS_SHORT_PRESS;
+ }
+
+ if (value & 0x1) {
+ /* send long push */
+ pr_debug(":MAD long push %d\n", value & 0x1);
+ present = 1;
+ jack_event_flag = 1;
+ buttonpressflag = 1;
+ mjack->jack.type = MID_JACK_HS_LONG_PRESS;
+ }
+
+ if (value & 0x8) {
+ if (!jack_det_enabled)
+ fs_pmic_irq_enable(intelmaddata);
+ /* send headset detect */
+ pr_debug(":MAD headset = %d\n", value & 0x8);
+ present = !(mjack->jack_status);
+ mjack->jack_status = present;
+ jack_event_flag = 1;
+ mjack->jack.type = SND_JACK_HEADSET;
+ }
+
+
+ if (jack_event_flag)
+ sst_mad_send_jack_report(&mjack->jack,
+ buttonpressflag, present);
+
+ return;
+}
+static int fs_jack_enable(void)
+{
+ return 0;
+}
+
struct snd_pmic_ops snd_pmic_ops_fs = {
.set_input_dev = fs_set_selected_input_dev,
.set_output_dev = fs_set_selected_output_dev,
@@ -765,9 +851,16 @@ struct snd_pmic_ops snd_pmic_ops_fs = {
.set_pcm_voice_params = fs_set_pcm_voice_params,
.set_voice_port = fs_set_voice_port,
.set_audio_port = fs_set_audio_port,
- .power_up_pmic_pb = fs_power_up_pb,
- .power_up_pmic_cp = fs_power_up_cp,
- .power_down_pmic_pb = fs_power_down_pb,
- .power_down_pmic_cp = fs_power_down_cp,
- .power_down_pmic = fs_power_down,
+ .power_up_pmic_pb = fs_power_up_pb,
+ .power_up_pmic_cp = fs_power_up_cp,
+ .power_down_pmic_pb = fs_power_down_pb,
+ .power_down_pmic_cp = fs_power_down_cp,
+ .power_down_pmic = fs_power_down,
+ .pmic_irq_cb = fs_pmic_irq_cb,
+ /*
+ * Jack detection enabling
+ * need be delayed till first IRQ happen.
+ */
+ .pmic_irq_enable = NULL,
+ .pmic_jack_enable = fs_jack_enable,
};