static int hp_dac_lim = 9;
module_param(hp_dac_lim, int, 0);
-/* Data for reading/writing to the IIR Filter hwdep */
-struct aic3x_iir_coeffs {
- short N0, N1, N2, D1, D2;
- short N3, N4, N5, D4, D5;
-};
-
struct aic3x_dacfilter_t {
struct aic3x_iir_coeffs coeffs;
int state;
{
static char curpage = -1;
u8 data[2], page = 0;
- printk("MNZ: aic3x_write(reg = %i, val = %x), curpage = %i\n",
- reg, value, curpage);
+
/*mutex_lock(&codec->mutex);*/
if (reg > 127){
reg -= 128;
page = 1;
}
+ //printk("MNZ: aic3x_write(reg = %i, val = 0x%x, page = %i)\n",
+ //reg, value, page);
if(reg && curpage != page){
data[0] = 0;
data[1] = page;
} else {
curpage = page;
}
- printk("MNZ: aic3x_write(), switched to page%i\n", curpage);
}
static const char *aic3x_adc_hpf[] =
{ "Disabled", "0.0045xFs", "0.0125xFs", "0.025xFs" };
static const char *aic3x_dac_filt[] =
- { "Off", "On", "Custom" };
+ { "Off", "Bass/Treble", "Custom" };
#define LDAC_ENUM 0
#define RDAC_ENUM 1
return 0;
}
-/* DAC Filter Functions */
+/* DAC and De-emphasis Filter Functions */
+int aic3x_deemph_set_coeffs(struct snd_soc_codec *codec,
+ int N0, int N1, int D1){
+ printk("MNZ: setting deemph coeffs\n");
+ snd_soc_update_bits(codec, AIC3X_CODEC_DFILT_CTRL, DEEMPH_ON, 0);
+
+ aic3x_write_coeff(codec, DEEMPH_LEFT_N0, N0);
+ aic3x_write_coeff(codec, DEEMPH_LEFT_N1, N1);
+ aic3x_write_coeff(codec, DEEMPH_LEFT_D1, D1);
+ aic3x_write_coeff(codec, DEEMPH_RIGHT_N0, N0);
+ aic3x_write_coeff(codec, DEEMPH_RIGHT_N1, N1);
+ aic3x_write_coeff(codec, DEEMPH_RIGHT_D1, D1);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(aic3x_deemph_set_coeffs);
+
+int aic3x_deemph_set_state(struct snd_soc_codec *codec, int state){
+ printk("MNZ: Setting De-Emph filter: %i\n", state);
+ if(state) state = DEEMPH_ON;
+ else state = 0;
+ return snd_soc_update_bits(codec, AIC3X_CODEC_DFILT_CTRL,
+ DEEMPH_ON, state);
+}
+EXPORT_SYMBOL_GPL(aic3x_deemph_set_state);
static int aic3x_dacfilter_write_coeffs
(struct snd_soc_codec *codec, struct aic3x_iir_coeffs *coeffs)
{
- struct aic3x_priv *aic3x = codec->private_data;
printk("MNZ: dacfilter_write_coeffs\n");
- snd_soc_update_bits(codec, AIC3X_CODEC_DFILT_CTRL, EFFECTS_ON, 0);
aic3x_write_coeff(codec, EFFECTS_LEFT_N0, coeffs->N0);
aic3x_write_coeff(codec, EFFECTS_LEFT_N1, coeffs->N1);
aic3x_write_coeff(codec, EFFECTS_LEFT_N2, coeffs->N2);
aic3x_write_coeff(codec, EFFECTS_RIGHT_D4, coeffs->D4);
aic3x_write_coeff(codec, EFFECTS_RIGHT_D5, coeffs->D5);
- snd_soc_update_bits(codec, AIC3X_CODEC_DFILT_CTRL, EFFECTS_ON, EFFECTS_ON);
+ return 1;
+}
+int aic3x_dacfilter_set_coeffs
+ (struct snd_soc_codec *codec, struct aic3x_iir_coeffs *coeffs)
+{
+ struct aic3x_priv *aic3x = codec->private_data;
memcpy((void*)&aic3x->dacfilter.coeffs, (void*)coeffs,
- sizeof(struct aic3x_iir_coeffs));
+ sizeof(struct aic3x_iir_coeffs));
+ if(aic3x->dacfilter.state == 2)
+ aic3x_dacfilter_set_state(codec, 0);
return 0;
}
+EXPORT_SYMBOL_GPL(aic3x_dacfilter_set_coeffs);
-static int aic3x_dacfilter_set_state(struct snd_soc_codec *codec,
- int state)
+int aic3x_dacfilter_set_state(struct snd_soc_codec *codec, int state)
{
+ printk("MNZ: dacfilter_set_state to %i\n", state);
struct aic3x_priv *aic3x = codec->private_data;
- printk("MNZ: dacfilter_set_state(state = %i)\n", state);
-
+ int ret = 0;
if(aic3x->dacfilter.state == state) return 0;
-
- aic3x->dacfilter.state = state;
- if(state == 0)
- snd_soc_update_bits(codec, AIC3X_CODEC_DFILT_CTRL,
+ snd_soc_update_bits(codec, AIC3X_CODEC_DFILT_CTRL,
EFFECTS_ON, 0);
- else if(state == 1) {}
+
+ if(state == 0)
+ ret = 1;
+ else if(state == 1)
+ ret = 1;
/* FIXME MNZ. Set preset from current chosen preset */
- else if (state == 2)
- return aic3x_dacfilter_write_coeffs(codec,
- &aic3x->dacfilter.coeffs);
- return 0;
+ else if (state == 2){
+ ret = aic3x_dacfilter_write_coeffs(codec,
+ &aic3x->dacfilter.coeffs);
+ if(ret) snd_soc_update_bits(codec, AIC3X_CODEC_DFILT_CTRL,
+ EFFECTS_ON, EFFECTS_ON);
+ }
+ else ret = 0;
+
+ if(ret) aic3x->dacfilter.state = state;
+ return ret;
}
+EXPORT_SYMBOL_GPL(aic3x_dacfilter_set_state);
+
/* DAC Filter hwdep device callbacks */
+static int snd_hwdep_dacfilter_open_aic3x(struct snd_hwdep *hw,
+ struct file *file)
+{
+ return 0;
+}
+
static int snd_hwdep_dacfilter_ioctl_aic3x(struct snd_hwdep *hw,
struct file *file, unsigned int cmd, unsigned long arg)
{
*/
struct snd_soc_codec *codec = hw->private_data;
if (cmd != 1) return -EINVAL;
+ printk("MNZ: IOCTL: cmd = %i, arg = %i\n", cmd, *((int*)arg));
return aic3x_dacfilter_set_state(codec, *((int*)arg));
- return 0;
}
static long snd_hwdep_dacfilter_read_aic3x(struct snd_hwdep *hw,
((struct aic3x_priv*)codec->private_data)->dacfilter.state = 2;
- return aic3x_dacfilter_write_coeffs(codec,
+ return aic3x_dacfilter_set_coeffs(codec,
(struct aic3x_iir_coeffs*)buf);
}
-/* DAC filter and 3D depth alsa controls callbacks */
+/* DAC filter and 3D depth ALSA controls callbacks */
static int snd_soc_get_dacfilter_aic3x(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
-printk("MNZ: get_dacfilter getting state: %i\n",((struct aic3x_priv*)codec->private_data)->dacfilter.state );
ucontrol->value.enumerated.item[0] =
((struct aic3x_priv*)codec->private_data)->dacfilter.state;
return 0;
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- printk("MNZ: put_dacfilter setting to %i\n", ucontrol->value.enumerated.item[0]);
if (ucontrol->value.enumerated.item[0] > 2)
return -EINVAL;
aic3x_dacfilter_set_state(codec, ucontrol->value.enumerated.item[0]);
{
struct snd_soc_codec *codec = socdev->codec;
struct aic3x_setup_data *setup = socdev->codec_data;
+ struct snd_hwdep *hwdep;
+ char hwdepid[] = "IIR Filter";
int reg, ret = 0;
+ printk("MNZ: BEGIN aic3x_init\n");
codec->name = "tlv320aic3x";
codec->owner = THIS_MODULE;
codec->read = aic3x_read_reg_cache;
aic3x_add_controls(codec);
aic3x_add_widgets(codec);
+
+ if(snd_hwdep_new(codec->card, hwdepid, 0, &hwdep) == 0){
+ hwdep->private_data = codec;
+ sprintf(hwdep->name, hwdepid);
+ hwdep->ops.open = snd_hwdep_dacfilter_open_aic3x;
+ hwdep->ops.ioctl = snd_hwdep_dacfilter_ioctl_aic3x;
+ hwdep->ops.read = snd_hwdep_dacfilter_read_aic3x;
+ hwdep->ops.write = snd_hwdep_dacfilter_write_aic3x;
+ ((struct aic3x_priv*)codec->private_data)->hwdep = hwdep;
+ }
+
ret = snd_soc_register_card(socdev);
+
if (ret < 0) {
printk(KERN_ERR "aic3x: failed to register card\n");
goto card_err;
/* Set some defaults for coefficients */
aic3x_write_coeff(codec, EFFECTS_3DATTEN, -32768);
+ printk("MNZ: END aic3x_init\n");
return ret;
struct aic3x_setup_data *setup;
struct snd_soc_codec *codec;
struct aic3x_priv *aic3x;
- struct snd_hwdep *hwdep;
int ret = 0;
printk(KERN_INFO "AIC3X Audio Codec %s\n", AIC3X_VERSION);
/* Add other interfaces here */
#endif
- if(snd_hwdep_new(codec->card, "IIR Filter", 0, &hwdep) == 0){
- printk("MNZ: hwdep initialized\n");
- hwdep->private_data = codec;
- hwdep->ops.ioctl = snd_hwdep_dacfilter_ioctl_aic3x;
- hwdep->ops.read = snd_hwdep_dacfilter_read_aic3x;
- hwdep->ops.write = snd_hwdep_dacfilter_write_aic3x;
- aic3x->hwdep = hwdep;
- }
-
if (ret != 0) {
kfree(codec->private_data);
kfree(codec);