aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorRoman Volkov <v1ron@mail.ru>2014-01-24 07:18:08 -0500
committerClemens Ladisch <clemens@ladisch.de>2014-01-29 14:45:46 -0500
commitbed61935cc5b70f84480dfd465c0e15a060c1f2c (patch)
treea347a0d361fafdf9110dd75d911df9e8b2031219 /sound
parentddd624c332698eb3ee5293bca6b5b3a97d05c0b6 (diff)
ALSA: oxygen: Xonar DG(X): add new CS4245 SPI functions
Add the new SPI write and read functions. The SPI read function is used for creating initial registers dump and may be used for debugging purposes. SPI operations are cached, so there is a new function to manage the cache (shadow). I have to remove the shift from the CS4245_SPI_* constants, since when we are performing the reading, we need to shift by 8 instead of 16. Signed-off-by: Roman Volkov <v1ron@mail.ru> Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
Diffstat (limited to 'sound')
-rw-r--r--sound/pci/oxygen/cs4245.h7
-rw-r--r--sound/pci/oxygen/xonar_dg.c63
-rw-r--r--sound/pci/oxygen/xonar_dg.h7
3 files changed, 73 insertions, 4 deletions
diff --git a/sound/pci/oxygen/cs4245.h b/sound/pci/oxygen/cs4245.h
index 5e0197e07dd1..99098657695a 100644
--- a/sound/pci/oxygen/cs4245.h
+++ b/sound/pci/oxygen/cs4245.h
@@ -102,6 +102,9 @@
102#define CS4245_ADC_OVFL 0x02 102#define CS4245_ADC_OVFL 0x02
103#define CS4245_ADC_UNDRFL 0x01 103#define CS4245_ADC_UNDRFL 0x01
104 104
105#define CS4245_SPI_ADDRESS_S (0x9e << 16)
106#define CS4245_SPI_WRITE_S (0 << 16)
105 107
106#define CS4245_SPI_ADDRESS (0x9e << 16) 108#define CS4245_SPI_ADDRESS 0x9e
107#define CS4245_SPI_WRITE (0 << 16) 109#define CS4245_SPI_WRITE 0
110#define CS4245_SPI_READ 1
diff --git a/sound/pci/oxygen/xonar_dg.c b/sound/pci/oxygen/xonar_dg.c
index c175720f1c7a..2518c611d5c5 100644
--- a/sound/pci/oxygen/xonar_dg.c
+++ b/sound/pci/oxygen/xonar_dg.c
@@ -64,6 +64,65 @@
64#include "xonar_dg.h" 64#include "xonar_dg.h"
65#include "cs4245.h" 65#include "cs4245.h"
66 66
67int cs4245_write_spi(struct oxygen *chip, u8 reg)
68{
69 struct dg *data = chip->model_data;
70 unsigned int packet;
71
72 packet = reg << 8;
73 packet |= (CS4245_SPI_ADDRESS | CS4245_SPI_WRITE) << 16;
74 packet |= data->cs4245_shadow[reg];
75
76 return oxygen_write_spi(chip, OXYGEN_SPI_TRIGGER |
77 OXYGEN_SPI_DATA_LENGTH_3 |
78 OXYGEN_SPI_CLOCK_1280 |
79 (0 << OXYGEN_SPI_CODEC_SHIFT) |
80 OXYGEN_SPI_CEN_LATCH_CLOCK_HI,
81 packet);
82}
83
84int cs4245_read_spi(struct oxygen *chip, u8 addr)
85{
86 struct dg *data = chip->model_data;
87 int ret;
88
89 ret = oxygen_write_spi(chip, OXYGEN_SPI_TRIGGER |
90 OXYGEN_SPI_DATA_LENGTH_2 |
91 OXYGEN_SPI_CEN_LATCH_CLOCK_HI |
92 OXYGEN_SPI_CLOCK_1280 | (0 << OXYGEN_SPI_CODEC_SHIFT),
93 ((CS4245_SPI_ADDRESS | CS4245_SPI_WRITE) << 8) | addr);
94 if (ret < 0)
95 return ret;
96
97 ret = oxygen_write_spi(chip, OXYGEN_SPI_TRIGGER |
98 OXYGEN_SPI_DATA_LENGTH_2 |
99 OXYGEN_SPI_CEN_LATCH_CLOCK_HI |
100 OXYGEN_SPI_CLOCK_1280 | (0 << OXYGEN_SPI_CODEC_SHIFT),
101 (CS4245_SPI_ADDRESS | CS4245_SPI_READ) << 8);
102 if (ret < 0)
103 return ret;
104
105 data->cs4245_shadow[addr] = oxygen_read8(chip, OXYGEN_SPI_DATA1);
106
107 return 0;
108}
109
110int cs4245_shadow_control(struct oxygen *chip, enum cs4245_shadow_operation op)
111{
112 struct dg *data = chip->model_data;
113 unsigned char addr;
114 int ret;
115
116 for (addr = 1; addr < ARRAY_SIZE(data->cs4245_shadow); addr++) {
117 ret = (op == CS4245_SAVE_TO_SHADOW ?
118 cs4245_read_spi(chip, addr) :
119 cs4245_write_spi(chip, addr));
120 if (ret < 0)
121 return ret;
122 }
123 return 0;
124}
125
67static void cs4245_write(struct oxygen *chip, unsigned int reg, u8 value) 126static void cs4245_write(struct oxygen *chip, unsigned int reg, u8 value)
68{ 127{
69 struct dg *data = chip->model_data; 128 struct dg *data = chip->model_data;
@@ -73,8 +132,8 @@ static void cs4245_write(struct oxygen *chip, unsigned int reg, u8 value)
73 OXYGEN_SPI_CLOCK_1280 | 132 OXYGEN_SPI_CLOCK_1280 |
74 (0 << OXYGEN_SPI_CODEC_SHIFT) | 133 (0 << OXYGEN_SPI_CODEC_SHIFT) |
75 OXYGEN_SPI_CEN_LATCH_CLOCK_HI, 134 OXYGEN_SPI_CEN_LATCH_CLOCK_HI,
76 CS4245_SPI_ADDRESS | 135 CS4245_SPI_ADDRESS_S |
77 CS4245_SPI_WRITE | 136 CS4245_SPI_WRITE_S |
78 (reg << 8) | value); 137 (reg << 8) | value);
79 data->cs4245_regs[reg] = value; 138 data->cs4245_regs[reg] = value;
80} 139}
diff --git a/sound/pci/oxygen/xonar_dg.h b/sound/pci/oxygen/xonar_dg.h
index 081269224850..f2fa846d7246 100644
--- a/sound/pci/oxygen/xonar_dg.h
+++ b/sound/pci/oxygen/xonar_dg.h
@@ -18,7 +18,14 @@
18#define PLAYBACK_DST_HP_FP 1 18#define PLAYBACK_DST_HP_FP 1
19#define PLAYBACK_DST_MULTICH 2 19#define PLAYBACK_DST_MULTICH 2
20 20
21enum cs4245_shadow_operation {
22 CS4245_SAVE_TO_SHADOW,
23 CS4245_LOAD_FROM_SHADOW
24};
25
21struct dg { 26struct dg {
27 /* shadow copy of the CS4245 register space */
28 unsigned char cs4245_shadow[17];
22 unsigned int output_sel; 29 unsigned int output_sel;
23 s8 input_vol[4][2]; 30 s8 input_vol[4][2];
24 unsigned int input_sel; 31 unsigned int input_sel;