2 * helper functions for Asus Xonar cards
4 * Copyright (c) Clemens Ladisch <clemens@ladisch.de>
7 * This driver is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License, version 2.
10 * This driver is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this driver; if not, see <http://www.gnu.org/licenses/>.
19 #include <linux/delay.h>
20 #include <sound/core.h>
21 #include <sound/control.h>
22 #include <sound/pcm.h>
23 #include <sound/pcm_params.h>
27 #define GPIO_CS53x1_M_MASK 0x000c
28 #define GPIO_CS53x1_M_SINGLE 0x0000
29 #define GPIO_CS53x1_M_DOUBLE 0x0004
30 #define GPIO_CS53x1_M_QUAD 0x0008
33 void xonar_enable_output(struct oxygen
*chip
)
35 struct xonar_generic
*data
= chip
->model_data
;
37 oxygen_set_bits16(chip
, OXYGEN_GPIO_CONTROL
, data
->output_enable_bit
);
38 msleep(data
->anti_pop_delay
);
39 oxygen_set_bits16(chip
, OXYGEN_GPIO_DATA
, data
->output_enable_bit
);
42 void xonar_disable_output(struct oxygen
*chip
)
44 struct xonar_generic
*data
= chip
->model_data
;
46 oxygen_clear_bits16(chip
, OXYGEN_GPIO_DATA
, data
->output_enable_bit
);
49 static void xonar_ext_power_gpio_changed(struct oxygen
*chip
)
51 struct xonar_generic
*data
= chip
->model_data
;
54 has_power
= !!(oxygen_read8(chip
, data
->ext_power_reg
)
55 & data
->ext_power_bit
);
56 if (has_power
!= data
->has_power
) {
57 data
->has_power
= has_power
;
59 snd_printk(KERN_NOTICE
"power restored\n");
62 "Hey! Don't unplug the power cable!\n");
68 void xonar_init_ext_power(struct oxygen
*chip
)
70 struct xonar_generic
*data
= chip
->model_data
;
72 oxygen_set_bits8(chip
, data
->ext_power_int_reg
,
74 chip
->interrupt_mask
|= OXYGEN_INT_GPIO
;
75 chip
->model
.gpio_changed
= xonar_ext_power_gpio_changed
;
76 data
->has_power
= !!(oxygen_read8(chip
, data
->ext_power_reg
)
77 & data
->ext_power_bit
);
80 void xonar_init_cs53x1(struct oxygen
*chip
)
82 oxygen_set_bits16(chip
, OXYGEN_GPIO_CONTROL
, GPIO_CS53x1_M_MASK
);
83 oxygen_write16_masked(chip
, OXYGEN_GPIO_DATA
,
84 GPIO_CS53x1_M_SINGLE
, GPIO_CS53x1_M_MASK
);
87 void xonar_set_cs53x1_params(struct oxygen
*chip
,
88 struct snd_pcm_hw_params
*params
)
92 if (params_rate(params
) <= 54000)
93 value
= GPIO_CS53x1_M_SINGLE
;
94 else if (params_rate(params
) <= 108000)
95 value
= GPIO_CS53x1_M_DOUBLE
;
97 value
= GPIO_CS53x1_M_QUAD
;
98 oxygen_write16_masked(chip
, OXYGEN_GPIO_DATA
,
99 value
, GPIO_CS53x1_M_MASK
);
102 int xonar_gpio_bit_switch_get(struct snd_kcontrol
*ctl
,
103 struct snd_ctl_elem_value
*value
)
105 struct oxygen
*chip
= ctl
->private_data
;
106 u16 bit
= ctl
->private_value
;
107 bool invert
= ctl
->private_value
& XONAR_GPIO_BIT_INVERT
;
109 value
->value
.integer
.value
[0] =
110 !!(oxygen_read16(chip
, OXYGEN_GPIO_DATA
) & bit
) ^ invert
;
114 int xonar_gpio_bit_switch_put(struct snd_kcontrol
*ctl
,
115 struct snd_ctl_elem_value
*value
)
117 struct oxygen
*chip
= ctl
->private_data
;
118 u16 bit
= ctl
->private_value
;
119 bool invert
= ctl
->private_value
& XONAR_GPIO_BIT_INVERT
;
120 u16 old_bits
, new_bits
;
123 spin_lock_irq(&chip
->reg_lock
);
124 old_bits
= oxygen_read16(chip
, OXYGEN_GPIO_DATA
);
125 if (!!value
->value
.integer
.value
[0] ^ invert
)
126 new_bits
= old_bits
| bit
;
128 new_bits
= old_bits
& ~bit
;
129 changed
= new_bits
!= old_bits
;
131 oxygen_write16(chip
, OXYGEN_GPIO_DATA
, new_bits
);
132 spin_unlock_irq(&chip
->reg_lock
);