0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <linux/init.h>
0010 #include <linux/i2c.h>
0011 #include <linux/kmod.h>
0012 #include <linux/slab.h>
0013 #include <sound/core.h>
0014 #include "pmac.h"
0015
0016
0017 #define DACA_I2C_ADDR 0x4d
0018
0019
0020 #define DACA_REG_SR 0x01
0021 #define DACA_REG_AVOL 0x02
0022 #define DACA_REG_GCFG 0x03
0023
0024
0025 #define DACA_VOL_MAX 0x38
0026
0027
0028 struct pmac_daca {
0029 struct pmac_keywest i2c;
0030 int left_vol, right_vol;
0031 unsigned int deemphasis : 1;
0032 unsigned int amp_on : 1;
0033 };
0034
0035
0036
0037
0038
0039 static int daca_init_client(struct pmac_keywest *i2c)
0040 {
0041 unsigned short wdata = 0x00;
0042
0043
0044 if (i2c_smbus_write_byte_data(i2c->client, DACA_REG_SR, 0x08) < 0 ||
0045 i2c_smbus_write_byte_data(i2c->client, DACA_REG_GCFG, 0x05) < 0)
0046 return -EINVAL;
0047 return i2c_smbus_write_block_data(i2c->client, DACA_REG_AVOL,
0048 2, (unsigned char*)&wdata);
0049 }
0050
0051
0052
0053
0054 static int daca_set_volume(struct pmac_daca *mix)
0055 {
0056 unsigned char data[2];
0057
0058 if (! mix->i2c.client)
0059 return -ENODEV;
0060
0061 if (mix->left_vol > DACA_VOL_MAX)
0062 data[0] = DACA_VOL_MAX;
0063 else
0064 data[0] = mix->left_vol;
0065 if (mix->right_vol > DACA_VOL_MAX)
0066 data[1] = DACA_VOL_MAX;
0067 else
0068 data[1] = mix->right_vol;
0069 data[1] |= mix->deemphasis ? 0x40 : 0;
0070 if (i2c_smbus_write_block_data(mix->i2c.client, DACA_REG_AVOL,
0071 2, data) < 0) {
0072 snd_printk(KERN_ERR "failed to set volume \n");
0073 return -EINVAL;
0074 }
0075 return 0;
0076 }
0077
0078
0079
0080 #define daca_info_deemphasis snd_ctl_boolean_mono_info
0081
0082 static int daca_get_deemphasis(struct snd_kcontrol *kcontrol,
0083 struct snd_ctl_elem_value *ucontrol)
0084 {
0085 struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
0086 struct pmac_daca *mix;
0087 mix = chip->mixer_data;
0088 if (!mix)
0089 return -ENODEV;
0090 ucontrol->value.integer.value[0] = mix->deemphasis ? 1 : 0;
0091 return 0;
0092 }
0093
0094 static int daca_put_deemphasis(struct snd_kcontrol *kcontrol,
0095 struct snd_ctl_elem_value *ucontrol)
0096 {
0097 struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
0098 struct pmac_daca *mix;
0099 int change;
0100
0101 mix = chip->mixer_data;
0102 if (!mix)
0103 return -ENODEV;
0104 change = mix->deemphasis != ucontrol->value.integer.value[0];
0105 if (change) {
0106 mix->deemphasis = !!ucontrol->value.integer.value[0];
0107 daca_set_volume(mix);
0108 }
0109 return change;
0110 }
0111
0112
0113 static int daca_info_volume(struct snd_kcontrol *kcontrol,
0114 struct snd_ctl_elem_info *uinfo)
0115 {
0116 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
0117 uinfo->count = 2;
0118 uinfo->value.integer.min = 0;
0119 uinfo->value.integer.max = DACA_VOL_MAX;
0120 return 0;
0121 }
0122
0123 static int daca_get_volume(struct snd_kcontrol *kcontrol,
0124 struct snd_ctl_elem_value *ucontrol)
0125 {
0126 struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
0127 struct pmac_daca *mix;
0128 mix = chip->mixer_data;
0129 if (!mix)
0130 return -ENODEV;
0131 ucontrol->value.integer.value[0] = mix->left_vol;
0132 ucontrol->value.integer.value[1] = mix->right_vol;
0133 return 0;
0134 }
0135
0136 static int daca_put_volume(struct snd_kcontrol *kcontrol,
0137 struct snd_ctl_elem_value *ucontrol)
0138 {
0139 struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
0140 struct pmac_daca *mix;
0141 unsigned int vol[2];
0142 int change;
0143
0144 mix = chip->mixer_data;
0145 if (!mix)
0146 return -ENODEV;
0147 vol[0] = ucontrol->value.integer.value[0];
0148 vol[1] = ucontrol->value.integer.value[1];
0149 if (vol[0] > DACA_VOL_MAX || vol[1] > DACA_VOL_MAX)
0150 return -EINVAL;
0151 change = mix->left_vol != vol[0] ||
0152 mix->right_vol != vol[1];
0153 if (change) {
0154 mix->left_vol = vol[0];
0155 mix->right_vol = vol[1];
0156 daca_set_volume(mix);
0157 }
0158 return change;
0159 }
0160
0161
0162 #define daca_info_amp daca_info_deemphasis
0163
0164 static int daca_get_amp(struct snd_kcontrol *kcontrol,
0165 struct snd_ctl_elem_value *ucontrol)
0166 {
0167 struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
0168 struct pmac_daca *mix;
0169 mix = chip->mixer_data;
0170 if (!mix)
0171 return -ENODEV;
0172 ucontrol->value.integer.value[0] = mix->amp_on ? 1 : 0;
0173 return 0;
0174 }
0175
0176 static int daca_put_amp(struct snd_kcontrol *kcontrol,
0177 struct snd_ctl_elem_value *ucontrol)
0178 {
0179 struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
0180 struct pmac_daca *mix;
0181 int change;
0182
0183 mix = chip->mixer_data;
0184 if (!mix)
0185 return -ENODEV;
0186 change = mix->amp_on != ucontrol->value.integer.value[0];
0187 if (change) {
0188 mix->amp_on = !!ucontrol->value.integer.value[0];
0189 i2c_smbus_write_byte_data(mix->i2c.client, DACA_REG_GCFG,
0190 mix->amp_on ? 0x05 : 0x04);
0191 }
0192 return change;
0193 }
0194
0195 static const struct snd_kcontrol_new daca_mixers[] = {
0196 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
0197 .name = "Deemphasis Switch",
0198 .info = daca_info_deemphasis,
0199 .get = daca_get_deemphasis,
0200 .put = daca_put_deemphasis
0201 },
0202 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
0203 .name = "Master Playback Volume",
0204 .info = daca_info_volume,
0205 .get = daca_get_volume,
0206 .put = daca_put_volume
0207 },
0208 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
0209 .name = "Power Amplifier Switch",
0210 .info = daca_info_amp,
0211 .get = daca_get_amp,
0212 .put = daca_put_amp
0213 },
0214 };
0215
0216
0217 #ifdef CONFIG_PM
0218 static void daca_resume(struct snd_pmac *chip)
0219 {
0220 struct pmac_daca *mix = chip->mixer_data;
0221 i2c_smbus_write_byte_data(mix->i2c.client, DACA_REG_SR, 0x08);
0222 i2c_smbus_write_byte_data(mix->i2c.client, DACA_REG_GCFG,
0223 mix->amp_on ? 0x05 : 0x04);
0224 daca_set_volume(mix);
0225 }
0226 #endif
0227
0228
0229 static void daca_cleanup(struct snd_pmac *chip)
0230 {
0231 struct pmac_daca *mix = chip->mixer_data;
0232 if (! mix)
0233 return;
0234 snd_pmac_keywest_cleanup(&mix->i2c);
0235 kfree(mix);
0236 chip->mixer_data = NULL;
0237 }
0238
0239
0240 int snd_pmac_daca_init(struct snd_pmac *chip)
0241 {
0242 int i, err;
0243 struct pmac_daca *mix;
0244
0245 request_module("i2c-powermac");
0246
0247 mix = kzalloc(sizeof(*mix), GFP_KERNEL);
0248 if (! mix)
0249 return -ENOMEM;
0250 chip->mixer_data = mix;
0251 chip->mixer_free = daca_cleanup;
0252 mix->amp_on = 1;
0253
0254 mix->i2c.addr = DACA_I2C_ADDR;
0255 mix->i2c.init_client = daca_init_client;
0256 mix->i2c.name = "DACA";
0257 err = snd_pmac_keywest_init(&mix->i2c);
0258 if (err < 0)
0259 return err;
0260
0261
0262
0263
0264 strcpy(chip->card->mixername, "PowerMac DACA");
0265
0266 for (i = 0; i < ARRAY_SIZE(daca_mixers); i++) {
0267 err = snd_ctl_add(chip->card, snd_ctl_new1(&daca_mixers[i], chip));
0268 if (err < 0)
0269 return err;
0270 }
0271
0272 #ifdef CONFIG_PM
0273 chip->resume = daca_resume;
0274 #endif
0275
0276 return 0;
0277 }