Skip to content

Commit

Permalink
tpa6130a2: Add headphone switch control
Browse files Browse the repository at this point in the history
Signed-off-by: Jan Grulich <jan@grulich.eu>
  • Loading branch information
popcornmix committed Dec 2, 2016
1 parent 2a1c50d commit 6da8c99
Showing 1 changed file with 60 additions and 0 deletions.
60 changes: 60 additions & 0 deletions sound/soc/codecs/tpa6130a2.c
Expand Up @@ -4,6 +4,7 @@
* Copyright (C) Nokia Corporation
*
* Author: Peter Ujfalusi <peter.ujfalusi@ti.com>
* Modified: Jan Grulich <jan@grulich.eu>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
Expand Down Expand Up @@ -50,6 +51,8 @@ struct tpa6130a2_data {
enum tpa_model id;
};

static void tpa6130a2_channel_enable(u8 channel, int enable);

static int tpa6130a2_power(struct tpa6130a2_data *data, bool enable)
{
int ret;
Expand Down Expand Up @@ -109,6 +112,20 @@ static int tpa6130a2_power_event(struct snd_soc_dapm_widget *w,
return 0;
}

static int tpa6130a2_put_hp_sw(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
int enable = ucontrol->value.integer.value[0];
unsigned int state;

state = (tpa6130a2_read(TPA6130A2_REG_VOL_MUTE) & 0x80) == 0;
if (state == enable)
return 0; /* No change */

tpa6130a2_channel_enable(TPA6130A2_HP_EN_R | TPA6130A2_HP_EN_L, enable);
return 1; /* Changed */
}

/*
* TPA6130 volume. From -59.5 to 4 dB with increasing step size when going
* down in gain.
Expand All @@ -130,6 +147,9 @@ static const struct snd_kcontrol_new tpa6130a2_controls[] = {
SOC_SINGLE_TLV("Headphone Playback Volume",
TPA6130A2_REG_VOL_MUTE, 0, 0x3f, 0,
tpa6130_tlv),
SOC_SINGLE_EXT("TPA6130A2 Headphone Playback Switch",
TPA6130A2_REG_VOL_MUTE, 7, 1, 1,
tpa6130a2_get_volsw, tpa6130a2_put_hp_sw),
};

static const DECLARE_TLV_DB_RANGE(tpa6140_tlv,
Expand All @@ -142,8 +162,48 @@ static const struct snd_kcontrol_new tpa6140a2_controls[] = {
SOC_SINGLE_TLV("Headphone Playback Volume",
TPA6130A2_REG_VOL_MUTE, 1, 0x1f, 0,
tpa6140_tlv),
SOC_SINGLE_EXT("TPA6140A2 Headphone Playback Switch",
TPA6130A2_REG_VOL_MUTE, 7, 1, 1,
tpa6130a2_get_volsw, tpa6130a2_put_hp_sw),
};

/*
* Enable or disable channel (left or right)
* The bit number for mute and amplifier are the same per channel:
* bit 6: Right channel
* bit 7: Left channel
* in both registers.
*/
static void tpa6130a2_channel_enable(u8 channel, int enable)
{
u8 val;

if (enable) {
/* Enable channel */
/* Enable amplifier */
val = tpa6130a2_read(TPA6130A2_REG_CONTROL);
val |= channel;
val &= ~TPA6130A2_SWS;
tpa6130a2_i2c_write(TPA6130A2_REG_CONTROL, val);

/* Unmute channel */
val = tpa6130a2_read(TPA6130A2_REG_VOL_MUTE);
val &= ~channel;
tpa6130a2_i2c_write(TPA6130A2_REG_VOL_MUTE, val);
} else {
/* Disable channel */
/* Mute channel */
val = tpa6130a2_read(TPA6130A2_REG_VOL_MUTE);
val |= channel;
tpa6130a2_i2c_write(TPA6130A2_REG_VOL_MUTE, val);

/* Disable amplifier */
val = tpa6130a2_read(TPA6130A2_REG_CONTROL);
val &= ~channel;
tpa6130a2_i2c_write(TPA6130A2_REG_CONTROL, val);
}
}

static int tpa6130a2_component_probe(struct snd_soc_component *component)
{
struct tpa6130a2_data *data = snd_soc_component_get_drvdata(component);
Expand Down

0 comments on commit 6da8c99

Please sign in to comment.