Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
3cabd442
Commit
3cabd442
authored
Oct 24, 2013
by
Mark Brown
Browse files
Options
Browse Files
Download
Plain Diff
Merge remote-tracking branch 'asoc/topic/tlv320aic26' into asoc-next
parents
2b48f86b
7fbdeb80
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
28 additions
and
116 deletions
+28
-116
sound/soc/codecs/tlv320aic26.c
sound/soc/codecs/tlv320aic26.c
+27
-112
sound/soc/codecs/tlv320aic26.h
sound/soc/codecs/tlv320aic26.h
+1
-4
No files found.
sound/soc/codecs/tlv320aic26.c
View file @
3cabd442
...
@@ -29,6 +29,7 @@ MODULE_LICENSE("GPL");
...
@@ -29,6 +29,7 @@ MODULE_LICENSE("GPL");
/* AIC26 driver private data */
/* AIC26 driver private data */
struct
aic26
{
struct
aic26
{
struct
spi_device
*
spi
;
struct
spi_device
*
spi
;
struct
regmap
*
regmap
;
struct
snd_soc_codec
*
codec
;
struct
snd_soc_codec
*
codec
;
int
master
;
int
master
;
int
datfm
;
int
datfm
;
...
@@ -40,85 +41,6 @@ struct aic26 {
...
@@ -40,85 +41,6 @@ struct aic26 {
int
keyclick_len
;
int
keyclick_len
;
};
};
/* ---------------------------------------------------------------------
* Register access routines
*/
static
unsigned
int
aic26_reg_read
(
struct
snd_soc_codec
*
codec
,
unsigned
int
reg
)
{
struct
aic26
*
aic26
=
snd_soc_codec_get_drvdata
(
codec
);
u16
*
cache
=
codec
->
reg_cache
;
u16
cmd
,
value
;
u8
buffer
[
2
];
int
rc
;
if
(
reg
>=
AIC26_NUM_REGS
)
{
WARN_ON_ONCE
(
1
);
return
0
;
}
/* Do SPI transfer; first 16bits are command; remaining is
* register contents */
cmd
=
AIC26_READ_COMMAND_WORD
(
reg
);
buffer
[
0
]
=
(
cmd
>>
8
)
&
0xff
;
buffer
[
1
]
=
cmd
&
0xff
;
rc
=
spi_write_then_read
(
aic26
->
spi
,
buffer
,
2
,
buffer
,
2
);
if
(
rc
)
{
dev_err
(
&
aic26
->
spi
->
dev
,
"AIC26 reg read error
\n
"
);
return
-
EIO
;
}
value
=
(
buffer
[
0
]
<<
8
)
|
buffer
[
1
];
/* Update the cache before returning with the value */
cache
[
reg
]
=
value
;
return
value
;
}
static
unsigned
int
aic26_reg_read_cache
(
struct
snd_soc_codec
*
codec
,
unsigned
int
reg
)
{
u16
*
cache
=
codec
->
reg_cache
;
if
(
reg
>=
AIC26_NUM_REGS
)
{
WARN_ON_ONCE
(
1
);
return
0
;
}
return
cache
[
reg
];
}
static
int
aic26_reg_write
(
struct
snd_soc_codec
*
codec
,
unsigned
int
reg
,
unsigned
int
value
)
{
struct
aic26
*
aic26
=
snd_soc_codec_get_drvdata
(
codec
);
u16
*
cache
=
codec
->
reg_cache
;
u16
cmd
;
u8
buffer
[
4
];
int
rc
;
if
(
reg
>=
AIC26_NUM_REGS
)
{
WARN_ON_ONCE
(
1
);
return
-
EINVAL
;
}
/* Do SPI transfer; first 16bits are command; remaining is data
* to write into register */
cmd
=
AIC26_WRITE_COMMAND_WORD
(
reg
);
buffer
[
0
]
=
(
cmd
>>
8
)
&
0xff
;
buffer
[
1
]
=
cmd
&
0xff
;
buffer
[
2
]
=
value
>>
8
;
buffer
[
3
]
=
value
;
rc
=
spi_write
(
aic26
->
spi
,
buffer
,
4
);
if
(
rc
)
{
dev_err
(
&
aic26
->
spi
->
dev
,
"AIC26 reg read error
\n
"
);
return
-
EIO
;
}
/* update cache before returning */
cache
[
reg
]
=
value
;
return
0
;
}
static
const
struct
snd_soc_dapm_widget
tlv320aic26_dapm_widgets
[]
=
{
static
const
struct
snd_soc_dapm_widget
tlv320aic26_dapm_widgets
[]
=
{
SND_SOC_DAPM_INPUT
(
"MICIN"
),
SND_SOC_DAPM_INPUT
(
"MICIN"
),
SND_SOC_DAPM_INPUT
(
"AUX"
),
SND_SOC_DAPM_INPUT
(
"AUX"
),
...
@@ -195,19 +117,15 @@ static int aic26_hw_params(struct snd_pcm_substream *substream,
...
@@ -195,19 +117,15 @@ static int aic26_hw_params(struct snd_pcm_substream *substream,
snd_soc_write
(
codec
,
AIC26_REG_PLL_PROG2
,
reg
);
snd_soc_write
(
codec
,
AIC26_REG_PLL_PROG2
,
reg
);
/* Audio Control 3 (master mode, fsref rate) */
/* Audio Control 3 (master mode, fsref rate) */
reg
=
aic26_reg_read_cache
(
codec
,
AIC26_REG_AUDIO_CTRL3
);
reg
&=
~
0xf800
;
if
(
aic26
->
master
)
if
(
aic26
->
master
)
reg
|
=
0x0800
;
reg
=
0x0800
;
if
(
fsref
==
48000
)
if
(
fsref
==
48000
)
reg
|
=
0x2000
;
reg
=
0x2000
;
snd_soc_
write
(
codec
,
AIC26_REG_AUDIO_CTRL3
,
reg
);
snd_soc_
update_bits
(
codec
,
AIC26_REG_AUDIO_CTRL3
,
0xf800
,
reg
);
/* Audio Control 1 (FSref divisor) */
/* Audio Control 1 (FSref divisor) */
reg
=
aic26_reg_read_cache
(
codec
,
AIC26_REG_AUDIO_CTRL1
);
reg
=
wlen
|
aic26
->
datfm
|
(
divisor
<<
3
)
|
divisor
;
reg
&=
~
0x0fff
;
snd_soc_update_bits
(
codec
,
AIC26_REG_AUDIO_CTRL1
,
0xfff
,
reg
);
reg
|=
wlen
|
aic26
->
datfm
|
(
divisor
<<
3
)
|
divisor
;
snd_soc_write
(
codec
,
AIC26_REG_AUDIO_CTRL1
,
reg
);
return
0
;
return
0
;
}
}
...
@@ -219,16 +137,16 @@ static int aic26_mute(struct snd_soc_dai *dai, int mute)
...
@@ -219,16 +137,16 @@ static int aic26_mute(struct snd_soc_dai *dai, int mute)
{
{
struct
snd_soc_codec
*
codec
=
dai
->
codec
;
struct
snd_soc_codec
*
codec
=
dai
->
codec
;
struct
aic26
*
aic26
=
snd_soc_codec_get_drvdata
(
codec
);
struct
aic26
*
aic26
=
snd_soc_codec_get_drvdata
(
codec
);
u16
reg
=
aic26_reg_read_cache
(
codec
,
AIC26_REG_DAC_GAIN
)
;
u16
reg
;
dev_dbg
(
&
aic26
->
spi
->
dev
,
"aic26_mute(dai=%p, mute=%i)
\n
"
,
dev_dbg
(
&
aic26
->
spi
->
dev
,
"aic26_mute(dai=%p, mute=%i)
\n
"
,
dai
,
mute
);
dai
,
mute
);
if
(
mute
)
if
(
mute
)
reg
|
=
0x8080
;
reg
=
0x8080
;
else
else
reg
&=
~
0x808
0
;
reg
=
0
;
snd_soc_
write
(
codec
,
AIC26_REG_DAC_GAIN
,
reg
);
snd_soc_
update_bits
(
codec
,
AIC26_REG_DAC_GAIN
,
0x8000
,
reg
);
return
0
;
return
0
;
}
}
...
@@ -346,7 +264,7 @@ static ssize_t aic26_keyclick_show(struct device *dev,
...
@@ -346,7 +264,7 @@ static ssize_t aic26_keyclick_show(struct device *dev,
struct
aic26
*
aic26
=
dev_get_drvdata
(
dev
);
struct
aic26
*
aic26
=
dev_get_drvdata
(
dev
);
int
val
,
amp
,
freq
,
len
;
int
val
,
amp
,
freq
,
len
;
val
=
aic26_reg_read_cache
(
aic26
->
codec
,
AIC26_REG_AUDIO_CTRL2
);
val
=
snd_soc_read
(
aic26
->
codec
,
AIC26_REG_AUDIO_CTRL2
);
amp
=
(
val
>>
12
)
&
0x7
;
amp
=
(
val
>>
12
)
&
0x7
;
freq
=
(
125
<<
((
val
>>
8
)
&
0x7
))
>>
1
;
freq
=
(
125
<<
((
val
>>
8
)
&
0x7
))
>>
1
;
len
=
2
*
(
1
+
((
val
>>
4
)
&
0xf
));
len
=
2
*
(
1
+
((
val
>>
4
)
&
0xf
));
...
@@ -360,11 +278,9 @@ static ssize_t aic26_keyclick_set(struct device *dev,
...
@@ -360,11 +278,9 @@ static ssize_t aic26_keyclick_set(struct device *dev,
const
char
*
buf
,
size_t
count
)
const
char
*
buf
,
size_t
count
)
{
{
struct
aic26
*
aic26
=
dev_get_drvdata
(
dev
);
struct
aic26
*
aic26
=
dev_get_drvdata
(
dev
);
int
val
;
val
=
aic26_reg_read_cache
(
aic26
->
codec
,
AIC26_REG_AUDIO_CTRL2
);
snd_soc_update_bits
(
aic26
->
codec
,
AIC26_REG_AUDIO_CTRL2
,
val
|=
0x8000
;
0x8000
,
0x800
);
snd_soc_write
(
aic26
->
codec
,
AIC26_REG_AUDIO_CTRL2
,
val
);
return
count
;
return
count
;
}
}
...
@@ -377,7 +293,9 @@ static DEVICE_ATTR(keyclick, 0644, aic26_keyclick_show, aic26_keyclick_set);
...
@@ -377,7 +293,9 @@ static DEVICE_ATTR(keyclick, 0644, aic26_keyclick_show, aic26_keyclick_set);
static
int
aic26_probe
(
struct
snd_soc_codec
*
codec
)
static
int
aic26_probe
(
struct
snd_soc_codec
*
codec
)
{
{
struct
aic26
*
aic26
=
dev_get_drvdata
(
codec
->
dev
);
struct
aic26
*
aic26
=
dev_get_drvdata
(
codec
->
dev
);
int
ret
,
err
,
i
,
reg
;
int
ret
,
reg
;
snd_soc_codec_set_cache_io
(
codec
,
16
,
16
,
SND_SOC_REGMAP
);
aic26
->
codec
=
codec
;
aic26
->
codec
=
codec
;
...
@@ -393,37 +311,30 @@ static int aic26_probe(struct snd_soc_codec *codec)
...
@@ -393,37 +311,30 @@ static int aic26_probe(struct snd_soc_codec *codec)
reg
|=
0x0800
;
/* set master mode */
reg
|=
0x0800
;
/* set master mode */
snd_soc_write
(
codec
,
AIC26_REG_AUDIO_CTRL3
,
reg
);
snd_soc_write
(
codec
,
AIC26_REG_AUDIO_CTRL3
,
reg
);
/* Fill register cache */
for
(
i
=
0
;
i
<
codec
->
driver
->
reg_cache_size
;
i
++
)
snd_soc_read
(
codec
,
i
);
/* Register the sysfs files for debugging */
/* Register the sysfs files for debugging */
/* Create SysFS files */
/* Create SysFS files */
ret
=
device_create_file
(
codec
->
dev
,
&
dev_attr_keyclick
);
ret
=
device_create_file
(
codec
->
dev
,
&
dev_attr_keyclick
);
if
(
ret
)
if
(
ret
)
dev_info
(
codec
->
dev
,
"error creating sysfs files
\n
"
);
dev_info
(
codec
->
dev
,
"error creating sysfs files
\n
"
);
/* register controls */
dev_dbg
(
codec
->
dev
,
"Registering controls
\n
"
);
err
=
snd_soc_add_codec_controls
(
codec
,
aic26_snd_controls
,
ARRAY_SIZE
(
aic26_snd_controls
));
WARN_ON
(
err
<
0
);
return
0
;
return
0
;
}
}
static
struct
snd_soc_codec_driver
aic26_soc_codec_dev
=
{
static
struct
snd_soc_codec_driver
aic26_soc_codec_dev
=
{
.
probe
=
aic26_probe
,
.
probe
=
aic26_probe
,
.
read
=
aic26_reg_read
,
.
controls
=
aic26_snd_controls
,
.
write
=
aic26_reg_write
,
.
num_controls
=
ARRAY_SIZE
(
aic26_snd_controls
),
.
reg_cache_size
=
AIC26_NUM_REGS
,
.
reg_word_size
=
sizeof
(
u16
),
.
dapm_widgets
=
tlv320aic26_dapm_widgets
,
.
dapm_widgets
=
tlv320aic26_dapm_widgets
,
.
num_dapm_widgets
=
ARRAY_SIZE
(
tlv320aic26_dapm_widgets
),
.
num_dapm_widgets
=
ARRAY_SIZE
(
tlv320aic26_dapm_widgets
),
.
dapm_routes
=
tlv320aic26_dapm_routes
,
.
dapm_routes
=
tlv320aic26_dapm_routes
,
.
num_dapm_routes
=
ARRAY_SIZE
(
tlv320aic26_dapm_routes
),
.
num_dapm_routes
=
ARRAY_SIZE
(
tlv320aic26_dapm_routes
),
};
};
static
const
struct
regmap_config
aic26_regmap
=
{
.
reg_bits
=
16
,
.
val_bits
=
16
,
};
/* ---------------------------------------------------------------------
/* ---------------------------------------------------------------------
* SPI device portion of driver: probe and release routines and SPI
* SPI device portion of driver: probe and release routines and SPI
* driver registration.
* driver registration.
...
@@ -440,6 +351,10 @@ static int aic26_spi_probe(struct spi_device *spi)
...
@@ -440,6 +351,10 @@ static int aic26_spi_probe(struct spi_device *spi)
if
(
!
aic26
)
if
(
!
aic26
)
return
-
ENOMEM
;
return
-
ENOMEM
;
aic26
->
regmap
=
devm_regmap_init_spi
(
spi
,
&
aic26_regmap
);
if
(
IS_ERR
(
aic26
->
regmap
))
return
PTR_ERR
(
aic26
->
regmap
);
/* Initialize the driver data */
/* Initialize the driver data */
aic26
->
spi
=
spi
;
aic26
->
spi
=
spi
;
dev_set_drvdata
(
&
spi
->
dev
,
aic26
);
dev_set_drvdata
(
&
spi
->
dev
,
aic26
);
...
...
sound/soc/codecs/tlv320aic26.h
View file @
3cabd442
...
@@ -9,10 +9,7 @@
...
@@ -9,10 +9,7 @@
#define _TLV320AIC16_H_
#define _TLV320AIC16_H_
/* AIC26 Registers */
/* AIC26 Registers */
#define AIC26_READ_COMMAND_WORD(addr) ((1 << 15) | (addr << 5))
#define AIC26_PAGE_ADDR(page, offset) ((page << 11) | offset << 5)
#define AIC26_WRITE_COMMAND_WORD(addr) ((0 << 15) | (addr << 5))
#define AIC26_PAGE_ADDR(page, offset) ((page << 6) | offset)
#define AIC26_NUM_REGS AIC26_PAGE_ADDR(3, 0)
/* Page 0: Auxiliary data registers */
/* Page 0: Auxiliary data registers */
#define AIC26_REG_BAT1 AIC26_PAGE_ADDR(0, 0x05)
#define AIC26_REG_BAT1 AIC26_PAGE_ADDR(0, 0x05)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment