root/sound/pci/oxygen/xonar_lib.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. xonar_enable_output
  2. xonar_disable_output
  3. xonar_ext_power_gpio_changed
  4. xonar_init_ext_power
  5. xonar_init_cs53x1
  6. xonar_set_cs53x1_params
  7. xonar_gpio_bit_switch_get
  8. xonar_gpio_bit_switch_put

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * helper functions for Asus Xonar cards
   4  *
   5  * Copyright (c) Clemens Ladisch <clemens@ladisch.de>
   6  */
   7 
   8 #include <linux/delay.h>
   9 #include <sound/core.h>
  10 #include <sound/control.h>
  11 #include <sound/pcm.h>
  12 #include <sound/pcm_params.h>
  13 #include "xonar.h"
  14 
  15 
  16 #define GPIO_CS53x1_M_MASK      0x000c
  17 #define GPIO_CS53x1_M_SINGLE    0x0000
  18 #define GPIO_CS53x1_M_DOUBLE    0x0004
  19 #define GPIO_CS53x1_M_QUAD      0x0008
  20 
  21 
  22 void xonar_enable_output(struct oxygen *chip)
  23 {
  24         struct xonar_generic *data = chip->model_data;
  25 
  26         oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL, data->output_enable_bit);
  27         msleep(data->anti_pop_delay);
  28         oxygen_set_bits16(chip, OXYGEN_GPIO_DATA, data->output_enable_bit);
  29 }
  30 
  31 void xonar_disable_output(struct oxygen *chip)
  32 {
  33         struct xonar_generic *data = chip->model_data;
  34 
  35         oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA, data->output_enable_bit);
  36 }
  37 
  38 static void xonar_ext_power_gpio_changed(struct oxygen *chip)
  39 {
  40         struct xonar_generic *data = chip->model_data;
  41         u8 has_power;
  42 
  43         has_power = !!(oxygen_read8(chip, data->ext_power_reg)
  44                        & data->ext_power_bit);
  45         if (has_power != data->has_power) {
  46                 data->has_power = has_power;
  47                 if (has_power) {
  48                         dev_notice(chip->card->dev, "power restored\n");
  49                 } else {
  50                         dev_crit(chip->card->dev,
  51                                    "Hey! Don't unplug the power cable!\n");
  52                         /* TODO: stop PCMs */
  53                 }
  54         }
  55 }
  56 
  57 void xonar_init_ext_power(struct oxygen *chip)
  58 {
  59         struct xonar_generic *data = chip->model_data;
  60 
  61         oxygen_set_bits8(chip, data->ext_power_int_reg,
  62                          data->ext_power_bit);
  63         chip->interrupt_mask |= OXYGEN_INT_GPIO;
  64         chip->model.gpio_changed = xonar_ext_power_gpio_changed;
  65         data->has_power = !!(oxygen_read8(chip, data->ext_power_reg)
  66                              & data->ext_power_bit);
  67 }
  68 
  69 void xonar_init_cs53x1(struct oxygen *chip)
  70 {
  71         oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL, GPIO_CS53x1_M_MASK);
  72         oxygen_write16_masked(chip, OXYGEN_GPIO_DATA,
  73                               GPIO_CS53x1_M_SINGLE, GPIO_CS53x1_M_MASK);
  74 }
  75 
  76 void xonar_set_cs53x1_params(struct oxygen *chip,
  77                              struct snd_pcm_hw_params *params)
  78 {
  79         unsigned int value;
  80 
  81         if (params_rate(params) <= 54000)
  82                 value = GPIO_CS53x1_M_SINGLE;
  83         else if (params_rate(params) <= 108000)
  84                 value = GPIO_CS53x1_M_DOUBLE;
  85         else
  86                 value = GPIO_CS53x1_M_QUAD;
  87         oxygen_write16_masked(chip, OXYGEN_GPIO_DATA,
  88                               value, GPIO_CS53x1_M_MASK);
  89 }
  90 
  91 int xonar_gpio_bit_switch_get(struct snd_kcontrol *ctl,
  92                               struct snd_ctl_elem_value *value)
  93 {
  94         struct oxygen *chip = ctl->private_data;
  95         u16 bit = ctl->private_value;
  96         bool invert = ctl->private_value & XONAR_GPIO_BIT_INVERT;
  97 
  98         value->value.integer.value[0] =
  99                 !!(oxygen_read16(chip, OXYGEN_GPIO_DATA) & bit) ^ invert;
 100         return 0;
 101 }
 102 
 103 int xonar_gpio_bit_switch_put(struct snd_kcontrol *ctl,
 104                               struct snd_ctl_elem_value *value)
 105 {
 106         struct oxygen *chip = ctl->private_data;
 107         u16 bit = ctl->private_value;
 108         bool invert = ctl->private_value & XONAR_GPIO_BIT_INVERT;
 109         u16 old_bits, new_bits;
 110         int changed;
 111 
 112         spin_lock_irq(&chip->reg_lock);
 113         old_bits = oxygen_read16(chip, OXYGEN_GPIO_DATA);
 114         if (!!value->value.integer.value[0] ^ invert)
 115                 new_bits = old_bits | bit;
 116         else
 117                 new_bits = old_bits & ~bit;
 118         changed = new_bits != old_bits;
 119         if (changed)
 120                 oxygen_write16(chip, OXYGEN_GPIO_DATA, new_bits);
 121         spin_unlock_irq(&chip->reg_lock);
 122         return changed;
 123 }

/* [<][>][^][v][top][bottom][index][help] */