-static int snd_ca0106_volume_get_analog_center_lfe(snd_kcontrol_t * kcontrol,
- snd_ctl_elem_value_t * ucontrol)
-{
- int channel_id = CONTROL_CENTER_LFE_CHANNEL;
- int reg = PLAYBACK_VOLUME2;
- return snd_ca0106_volume_get(kcontrol, ucontrol, reg, channel_id);
-}
-static int snd_ca0106_volume_get_analog_unknown(snd_kcontrol_t * kcontrol,
- snd_ctl_elem_value_t * ucontrol)
-{
- int channel_id = CONTROL_UNKNOWN_CHANNEL;
- int reg = PLAYBACK_VOLUME2;
- return snd_ca0106_volume_get(kcontrol, ucontrol, reg, channel_id);
-}
-static int snd_ca0106_volume_get_analog_rear(snd_kcontrol_t * kcontrol,
- snd_ctl_elem_value_t * ucontrol)
-{
- int channel_id = CONTROL_REAR_CHANNEL;
- int reg = PLAYBACK_VOLUME2;
- return snd_ca0106_volume_get(kcontrol, ucontrol, reg, channel_id);
-}
-
-static int snd_ca0106_volume_get_feedback(snd_kcontrol_t * kcontrol,
- snd_ctl_elem_value_t * ucontrol)
-{
- int channel_id = 1;
- int reg = CAPTURE_CONTROL;
- return snd_ca0106_volume_get(kcontrol, ucontrol, reg, channel_id);
-}
-
-static int snd_ca0106_volume_put(snd_kcontrol_t * kcontrol,
- snd_ctl_elem_value_t * ucontrol, int reg, int channel_id)
-{
- ca0106_t *emu = snd_kcontrol_chip(kcontrol);
- unsigned int value;
- //value = snd_ca0106_ptr_read(emu, reg, channel_id);
- //value = value & 0xffff;
- value = ((0xff - ucontrol->value.integer.value[0]) << 24) | ((0xff - ucontrol->value.integer.value[1]) << 16);
- value = value | ((0xff - ucontrol->value.integer.value[0]) << 8) | ((0xff - ucontrol->value.integer.value[1]) );
- snd_ca0106_ptr_write(emu, reg, channel_id, value);
- return 1;
-}
-static int snd_ca0106_volume_put_spdif_front(snd_kcontrol_t * kcontrol,
- snd_ctl_elem_value_t * ucontrol)
-{
- int channel_id = CONTROL_FRONT_CHANNEL;
- int reg = PLAYBACK_VOLUME1;
- return snd_ca0106_volume_put(kcontrol, ucontrol, reg, channel_id);
-}
-static int snd_ca0106_volume_put_spdif_center_lfe(snd_kcontrol_t * kcontrol,
- snd_ctl_elem_value_t * ucontrol)
-{
- int channel_id = CONTROL_CENTER_LFE_CHANNEL;
- int reg = PLAYBACK_VOLUME1;
- return snd_ca0106_volume_put(kcontrol, ucontrol, reg, channel_id);
-}
-static int snd_ca0106_volume_put_spdif_unknown(snd_kcontrol_t * kcontrol,
- snd_ctl_elem_value_t * ucontrol)
-{
- int channel_id = CONTROL_UNKNOWN_CHANNEL;
- int reg = PLAYBACK_VOLUME1;
- return snd_ca0106_volume_put(kcontrol, ucontrol, reg, channel_id);
-}
-static int snd_ca0106_volume_put_spdif_rear(snd_kcontrol_t * kcontrol,
- snd_ctl_elem_value_t * ucontrol)
-{
- int channel_id = CONTROL_REAR_CHANNEL;
- int reg = PLAYBACK_VOLUME1;
- return snd_ca0106_volume_put(kcontrol, ucontrol, reg, channel_id);
-}
-static int snd_ca0106_volume_put_analog_front(snd_kcontrol_t * kcontrol,
- snd_ctl_elem_value_t * ucontrol)
-{
- int channel_id = CONTROL_FRONT_CHANNEL;
- int reg = PLAYBACK_VOLUME2;
- return snd_ca0106_volume_put(kcontrol, ucontrol, reg, channel_id);
-}
-static int snd_ca0106_volume_put_analog_center_lfe(snd_kcontrol_t * kcontrol,
- snd_ctl_elem_value_t * ucontrol)
-{
- int channel_id = CONTROL_CENTER_LFE_CHANNEL;
- int reg = PLAYBACK_VOLUME2;
- return snd_ca0106_volume_put(kcontrol, ucontrol, reg, channel_id);
-}
-static int snd_ca0106_volume_put_analog_unknown(snd_kcontrol_t * kcontrol,
- snd_ctl_elem_value_t * ucontrol)
-{
- int channel_id = CONTROL_UNKNOWN_CHANNEL;
- int reg = PLAYBACK_VOLUME2;
- return snd_ca0106_volume_put(kcontrol, ucontrol, reg, channel_id);
-}
-static int snd_ca0106_volume_put_analog_rear(snd_kcontrol_t * kcontrol,
- snd_ctl_elem_value_t * ucontrol)
-{
- int channel_id = CONTROL_REAR_CHANNEL;
- int reg = PLAYBACK_VOLUME2;
- return snd_ca0106_volume_put(kcontrol, ucontrol, reg, channel_id);
-}
-
-static int snd_ca0106_volume_put_feedback(snd_kcontrol_t * kcontrol,
- snd_ctl_elem_value_t * ucontrol)
-{
- int channel_id = 1;
- int reg = CAPTURE_CONTROL;
- return snd_ca0106_volume_put(kcontrol, ucontrol, reg, channel_id);
-}
-
-static snd_kcontrol_new_t snd_ca0106_volume_control_analog_front =
-{
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Analog Front Volume",
- .info = snd_ca0106_volume_info,
- .get = snd_ca0106_volume_get_analog_front,
- .put = snd_ca0106_volume_put_analog_front
-};
-static snd_kcontrol_new_t snd_ca0106_volume_control_analog_center_lfe =
-{
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Analog Center/LFE Volume",
- .info = snd_ca0106_volume_info,
- .get = snd_ca0106_volume_get_analog_center_lfe,
- .put = snd_ca0106_volume_put_analog_center_lfe
-};
-static snd_kcontrol_new_t snd_ca0106_volume_control_analog_unknown =
-{
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Analog Unknown Volume",
- .info = snd_ca0106_volume_info,
- .get = snd_ca0106_volume_get_analog_unknown,
- .put = snd_ca0106_volume_put_analog_unknown
-};
-static snd_kcontrol_new_t snd_ca0106_volume_control_analog_rear =
-{
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Analog Rear Volume",
- .info = snd_ca0106_volume_info,
- .get = snd_ca0106_volume_get_analog_rear,
- .put = snd_ca0106_volume_put_analog_rear
-};
-static snd_kcontrol_new_t snd_ca0106_volume_control_spdif_front =
-{
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "SPDIF Front Volume",
- .info = snd_ca0106_volume_info,
- .get = snd_ca0106_volume_get_spdif_front,
- .put = snd_ca0106_volume_put_spdif_front
-};
-static snd_kcontrol_new_t snd_ca0106_volume_control_spdif_center_lfe =
-{
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "SPDIF Center/LFE Volume",
- .info = snd_ca0106_volume_info,
- .get = snd_ca0106_volume_get_spdif_center_lfe,
- .put = snd_ca0106_volume_put_spdif_center_lfe
-};
-static snd_kcontrol_new_t snd_ca0106_volume_control_spdif_unknown =
-{
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "SPDIF Unknown Volume",
- .info = snd_ca0106_volume_info,
- .get = snd_ca0106_volume_get_spdif_unknown,
- .put = snd_ca0106_volume_put_spdif_unknown
-};
-static snd_kcontrol_new_t snd_ca0106_volume_control_spdif_rear =
-{
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "SPDIF Rear Volume",
- .info = snd_ca0106_volume_info,
- .get = snd_ca0106_volume_get_spdif_rear,
- .put = snd_ca0106_volume_put_spdif_rear
-};
-
-static snd_kcontrol_new_t snd_ca0106_volume_control_feedback =
-{
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "CAPTURE feedback into PLAYBACK",
- .info = snd_ca0106_volume_info,
- .get = snd_ca0106_volume_get_feedback,
- .put = snd_ca0106_volume_put_feedback
+ oval = snd_ca0106_ptr_read(emu, reg, channel_id);
+ nval = ((0xff - ucontrol->value.integer.value[0]) << 24) |
+ ((0xff - ucontrol->value.integer.value[1]) << 16);
+ nval |= ((0xff - ucontrol->value.integer.value[0]) << 8) |
+ ((0xff - ucontrol->value.integer.value[1]) );
+ if (oval == nval)
+ return 0;
+ snd_ca0106_ptr_write(emu, reg, channel_id, nval);
+ return 1;
+}
+
+#define CA_VOLUME(xname,chid,reg) \
+{ \
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
+ .info = snd_ca0106_volume_info, \
+ .get = snd_ca0106_volume_get, \
+ .put = snd_ca0106_volume_put, \
+ .private_value = ((chid) << 8) | (reg) \
+}
+
+
+static struct snd_kcontrol_new snd_ca0106_volume_ctls[] __devinitdata = {
+ CA_VOLUME("Analog Front Playback Volume",
+ CONTROL_FRONT_CHANNEL, PLAYBACK_VOLUME2),
+ CA_VOLUME("Analog Rear Playback Volume",
+ CONTROL_REAR_CHANNEL, PLAYBACK_VOLUME2),
+ CA_VOLUME("Analog Center/LFE Playback Volume",
+ CONTROL_CENTER_LFE_CHANNEL, PLAYBACK_VOLUME2),
+ CA_VOLUME("Analog Side Playback Volume",
+ CONTROL_UNKNOWN_CHANNEL, PLAYBACK_VOLUME2),
+
+ CA_VOLUME("IEC958 Front Playback Volume",
+ CONTROL_FRONT_CHANNEL, PLAYBACK_VOLUME1),
+ CA_VOLUME("IEC958 Rear Playback Volume",
+ CONTROL_REAR_CHANNEL, PLAYBACK_VOLUME1),
+ CA_VOLUME("IEC958 Center/LFE Playback Volume",
+ CONTROL_CENTER_LFE_CHANNEL, PLAYBACK_VOLUME1),
+ CA_VOLUME("IEC958 Unknown Playback Volume",
+ CONTROL_UNKNOWN_CHANNEL, PLAYBACK_VOLUME1),
+
+ CA_VOLUME("CAPTURE feedback Playback Volume",
+ 1, CAPTURE_CONTROL),
+
+ {
+ .access = SNDRV_CTL_ELEM_ACCESS_READ,
+ .iface = SNDRV_CTL_ELEM_IFACE_PCM,
+ .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,MASK),
+ .count = 4,
+ .info = snd_ca0106_spdif_info,
+ .get = snd_ca0106_spdif_get_mask
+ },
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "IEC958 Playback Switch",
+ .info = snd_ca0106_shared_spdif_info,
+ .get = snd_ca0106_shared_spdif_get,
+ .put = snd_ca0106_shared_spdif_put
+ },
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "Capture Source",
+ .info = snd_ca0106_capture_source_info,
+ .get = snd_ca0106_capture_source_get,
+ .put = snd_ca0106_capture_source_put
+ },
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_PCM,
+ .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
+ .count = 4,
+ .info = snd_ca0106_spdif_info,
+ .get = snd_ca0106_spdif_get,
+ .put = snd_ca0106_spdif_put
+ },