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
nexedi
linux
Commits
b4d032b3
Commit
b4d032b3
authored
Mar 23, 2014
by
Mark Brown
Browse files
Options
Browse Files
Download
Plain Diff
Merge remote-tracking branch 'asoc/topic/cs42xx8' into asoc-next
parents
f928badf
0c516b4f
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
946 additions
and
0 deletions
+946
-0
Documentation/devicetree/bindings/sound/cs42xx8.txt
Documentation/devicetree/bindings/sound/cs42xx8.txt
+28
-0
sound/soc/codecs/Kconfig
sound/soc/codecs/Kconfig
+10
-0
sound/soc/codecs/Makefile
sound/soc/codecs/Makefile
+4
-0
sound/soc/codecs/cs42xx8-i2c.c
sound/soc/codecs/cs42xx8-i2c.c
+64
-0
sound/soc/codecs/cs42xx8.c
sound/soc/codecs/cs42xx8.c
+602
-0
sound/soc/codecs/cs42xx8.h
sound/soc/codecs/cs42xx8.h
+238
-0
No files found.
Documentation/devicetree/bindings/sound/cs42xx8.txt
0 → 100644
View file @
b4d032b3
CS42448/CS42888 audio CODEC
Required properties:
- compatible : must contain one of "cirrus,cs42448" and "cirrus,cs42888"
- reg : the I2C address of the device for I2C
- clocks : a list of phandles + clock-specifiers, one for each entry in
clock-names
- clock-names : must contain "mclk"
- VA-supply, VD-supply, VLS-supply, VLC-supply: power supplies for the device,
as covered in Documentation/devicetree/bindings/regulator/regulator.txt
Example:
codec: cs42888@48 {
compatible = "cirrus,cs42888";
reg = <0x48>;
clocks = <&codec_mclk 0>;
clock-names = "mclk";
VA-supply = <®_audio>;
VD-supply = <®_audio>;
VLS-supply = <®_audio>;
VLC-supply = <®_audio>;
};
sound/soc/codecs/Kconfig
View file @
b4d032b3
...
@@ -44,6 +44,7 @@ config SND_SOC_ALL_CODECS
...
@@ -44,6 +44,7 @@ config SND_SOC_ALL_CODECS
select SND_SOC_CS42L73 if I2C
select SND_SOC_CS42L73 if I2C
select SND_SOC_CS4270 if I2C
select SND_SOC_CS4270 if I2C
select SND_SOC_CS4271 if SND_SOC_I2C_AND_SPI
select SND_SOC_CS4271 if SND_SOC_I2C_AND_SPI
select SND_SOC_CS42XX8_I2C if I2C
select SND_SOC_CX20442 if TTY
select SND_SOC_CX20442 if TTY
select SND_SOC_DA7210 if I2C
select SND_SOC_DA7210 if I2C
select SND_SOC_DA7213 if I2C
select SND_SOC_DA7213 if I2C
...
@@ -304,6 +305,15 @@ config SND_SOC_CS4271
...
@@ -304,6 +305,15 @@ config SND_SOC_CS4271
tristate "Cirrus Logic CS4271 CODEC"
tristate "Cirrus Logic CS4271 CODEC"
depends on SND_SOC_I2C_AND_SPI
depends on SND_SOC_I2C_AND_SPI
config SND_SOC_CS42XX8
tristate
config SND_SOC_CS42XX8_I2C
tristate "Cirrus Logic CS42448/CS42888 CODEC (I2C)"
depends on I2C
select SND_SOC_CS42XX8
select REGMAP_I2C
config SND_SOC_CX20442
config SND_SOC_CX20442
tristate
tristate
depends on TTY
depends on TTY
...
...
sound/soc/codecs/Makefile
View file @
b4d032b3
...
@@ -30,6 +30,8 @@ snd-soc-cs42l52-objs := cs42l52.o
...
@@ -30,6 +30,8 @@ snd-soc-cs42l52-objs := cs42l52.o
snd-soc-cs42l73-objs
:=
cs42l73.o
snd-soc-cs42l73-objs
:=
cs42l73.o
snd-soc-cs4270-objs
:=
cs4270.o
snd-soc-cs4270-objs
:=
cs4270.o
snd-soc-cs4271-objs
:=
cs4271.o
snd-soc-cs4271-objs
:=
cs4271.o
snd-soc-cs42xx8-objs
:=
cs42xx8.o
snd-soc-cs42xx8-i2c-objs
:=
cs42xx8-i2c.o
snd-soc-cx20442-objs
:=
cx20442.o
snd-soc-cx20442-objs
:=
cx20442.o
snd-soc-da7210-objs
:=
da7210.o
snd-soc-da7210-objs
:=
da7210.o
snd-soc-da7213-objs
:=
da7213.o
snd-soc-da7213-objs
:=
da7213.o
...
@@ -179,6 +181,8 @@ obj-$(CONFIG_SND_SOC_CS42L52) += snd-soc-cs42l52.o
...
@@ -179,6 +181,8 @@ obj-$(CONFIG_SND_SOC_CS42L52) += snd-soc-cs42l52.o
obj-$(CONFIG_SND_SOC_CS42L73)
+=
snd-soc-cs42l73.o
obj-$(CONFIG_SND_SOC_CS42L73)
+=
snd-soc-cs42l73.o
obj-$(CONFIG_SND_SOC_CS4270)
+=
snd-soc-cs4270.o
obj-$(CONFIG_SND_SOC_CS4270)
+=
snd-soc-cs4270.o
obj-$(CONFIG_SND_SOC_CS4271)
+=
snd-soc-cs4271.o
obj-$(CONFIG_SND_SOC_CS4271)
+=
snd-soc-cs4271.o
obj-$(CONFIG_SND_SOC_CS42XX8)
+=
snd-soc-cs42xx8.o
obj-$(CONFIG_SND_SOC_CS42XX8_I2C)
+=
snd-soc-cs42xx8-i2c.o
obj-$(CONFIG_SND_SOC_CX20442)
+=
snd-soc-cx20442.o
obj-$(CONFIG_SND_SOC_CX20442)
+=
snd-soc-cx20442.o
obj-$(CONFIG_SND_SOC_DA7210)
+=
snd-soc-da7210.o
obj-$(CONFIG_SND_SOC_DA7210)
+=
snd-soc-da7210.o
obj-$(CONFIG_SND_SOC_DA7213)
+=
snd-soc-da7213.o
obj-$(CONFIG_SND_SOC_DA7213)
+=
snd-soc-da7213.o
...
...
sound/soc/codecs/cs42xx8-i2c.c
0 → 100644
View file @
b4d032b3
/*
* Cirrus Logic CS42448/CS42888 Audio CODEC DAI I2C driver
*
* Copyright (C) 2014 Freescale Semiconductor, Inc.
*
* Author: Nicolin Chen <Guangyu.Chen@freescale.com>
*
* This file is licensed under the terms of the GNU General Public License
* version 2. This program is licensed "as is" without any warranty of any
* kind, whether express or implied.
*/
#include <linux/i2c.h>
#include <linux/module.h>
#include <linux/pm_runtime.h>
#include <sound/soc.h>
#include "cs42xx8.h"
static
int
cs42xx8_i2c_probe
(
struct
i2c_client
*
i2c
,
const
struct
i2c_device_id
*
id
)
{
u32
ret
=
cs42xx8_probe
(
&
i2c
->
dev
,
devm_regmap_init_i2c
(
i2c
,
&
cs42xx8_regmap_config
));
if
(
ret
)
return
ret
;
pm_runtime_enable
(
&
i2c
->
dev
);
pm_request_idle
(
&
i2c
->
dev
);
return
0
;
}
static
int
cs42xx8_i2c_remove
(
struct
i2c_client
*
i2c
)
{
snd_soc_unregister_codec
(
&
i2c
->
dev
);
pm_runtime_disable
(
&
i2c
->
dev
);
return
0
;
}
static
struct
i2c_device_id
cs42xx8_i2c_id
[]
=
{
{
"cs42448"
,
(
kernel_ulong_t
)
&
cs42448_data
},
{
"cs42888"
,
(
kernel_ulong_t
)
&
cs42888_data
},
{}
};
MODULE_DEVICE_TABLE
(
i2c
,
cs42xx8_i2c_id
);
static
struct
i2c_driver
cs42xx8_i2c_driver
=
{
.
driver
=
{
.
name
=
"cs42xx8"
,
.
owner
=
THIS_MODULE
,
.
pm
=
&
cs42xx8_pm
,
},
.
probe
=
cs42xx8_i2c_probe
,
.
remove
=
cs42xx8_i2c_remove
,
.
id_table
=
cs42xx8_i2c_id
,
};
module_i2c_driver
(
cs42xx8_i2c_driver
);
MODULE_DESCRIPTION
(
"Cirrus Logic CS42448/CS42888 ALSA SoC Codec I2C Driver"
);
MODULE_AUTHOR
(
"Freescale Semiconductor, Inc."
);
MODULE_LICENSE
(
"GPL"
);
sound/soc/codecs/cs42xx8.c
0 → 100644
View file @
b4d032b3
/*
* Cirrus Logic CS42448/CS42888 Audio CODEC Digital Audio Interface (DAI) driver
*
* Copyright (C) 2014 Freescale Semiconductor, Inc.
*
* Author: Nicolin Chen <Guangyu.Chen@freescale.com>
*
* This file is licensed under the terms of the GNU General Public License
* version 2. This program is licensed "as is" without any warranty of any
* kind, whether express or implied.
*/
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/pm_runtime.h>
#include <linux/regulator/consumer.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
#include <sound/tlv.h>
#include "cs42xx8.h"
#define CS42XX8_NUM_SUPPLIES 4
static
const
char
*
const
cs42xx8_supply_names
[
CS42XX8_NUM_SUPPLIES
]
=
{
"VA"
,
"VD"
,
"VLS"
,
"VLC"
,
};
#define CS42XX8_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
SNDRV_PCM_FMTBIT_S20_3LE | \
SNDRV_PCM_FMTBIT_S24_LE | \
SNDRV_PCM_FMTBIT_S32_LE)
/* codec private data */
struct
cs42xx8_priv
{
struct
regulator_bulk_data
supplies
[
CS42XX8_NUM_SUPPLIES
];
const
struct
cs42xx8_driver_data
*
drvdata
;
struct
regmap
*
regmap
;
struct
clk
*
clk
;
bool
slave_mode
;
unsigned
long
sysclk
;
};
/* -127.5dB to 0dB with step of 0.5dB */
static
const
DECLARE_TLV_DB_SCALE
(
dac_tlv
,
-
12750
,
50
,
1
);
/* -64dB to 24dB with step of 0.5dB */
static
const
DECLARE_TLV_DB_SCALE
(
adc_tlv
,
-
6400
,
50
,
0
);
static
const
char
*
const
cs42xx8_adc_single
[]
=
{
"Differential"
,
"Single-Ended"
};
static
const
char
*
const
cs42xx8_szc
[]
=
{
"Immediate Change"
,
"Zero Cross"
,
"Soft Ramp"
,
"Soft Ramp on Zero Cross"
};
static
const
struct
soc_enum
adc1_single_enum
=
SOC_ENUM_SINGLE
(
CS42XX8_ADCCTL
,
4
,
2
,
cs42xx8_adc_single
);
static
const
struct
soc_enum
adc2_single_enum
=
SOC_ENUM_SINGLE
(
CS42XX8_ADCCTL
,
3
,
2
,
cs42xx8_adc_single
);
static
const
struct
soc_enum
adc3_single_enum
=
SOC_ENUM_SINGLE
(
CS42XX8_ADCCTL
,
2
,
2
,
cs42xx8_adc_single
);
static
const
struct
soc_enum
dac_szc_enum
=
SOC_ENUM_SINGLE
(
CS42XX8_TXCTL
,
5
,
4
,
cs42xx8_szc
);
static
const
struct
soc_enum
adc_szc_enum
=
SOC_ENUM_SINGLE
(
CS42XX8_TXCTL
,
0
,
4
,
cs42xx8_szc
);
static
const
struct
snd_kcontrol_new
cs42xx8_snd_controls
[]
=
{
SOC_DOUBLE_R_TLV
(
"DAC1 Playback Volume"
,
CS42XX8_VOLAOUT1
,
CS42XX8_VOLAOUT2
,
0
,
0xff
,
1
,
dac_tlv
),
SOC_DOUBLE_R_TLV
(
"DAC2 Playback Volume"
,
CS42XX8_VOLAOUT3
,
CS42XX8_VOLAOUT4
,
0
,
0xff
,
1
,
dac_tlv
),
SOC_DOUBLE_R_TLV
(
"DAC3 Playback Volume"
,
CS42XX8_VOLAOUT5
,
CS42XX8_VOLAOUT6
,
0
,
0xff
,
1
,
dac_tlv
),
SOC_DOUBLE_R_TLV
(
"DAC4 Playback Volume"
,
CS42XX8_VOLAOUT7
,
CS42XX8_VOLAOUT8
,
0
,
0xff
,
1
,
dac_tlv
),
SOC_DOUBLE_R_S_TLV
(
"ADC1 Capture Volume"
,
CS42XX8_VOLAIN1
,
CS42XX8_VOLAIN2
,
0
,
-
0x80
,
0x30
,
7
,
0
,
adc_tlv
),
SOC_DOUBLE_R_S_TLV
(
"ADC2 Capture Volume"
,
CS42XX8_VOLAIN3
,
CS42XX8_VOLAIN4
,
0
,
-
0x80
,
0x30
,
7
,
0
,
adc_tlv
),
SOC_DOUBLE
(
"DAC1 Invert Switch"
,
CS42XX8_DACINV
,
0
,
1
,
1
,
0
),
SOC_DOUBLE
(
"DAC2 Invert Switch"
,
CS42XX8_DACINV
,
2
,
3
,
1
,
0
),
SOC_DOUBLE
(
"DAC3 Invert Switch"
,
CS42XX8_DACINV
,
4
,
5
,
1
,
0
),
SOC_DOUBLE
(
"DAC4 Invert Switch"
,
CS42XX8_DACINV
,
6
,
7
,
1
,
0
),
SOC_DOUBLE
(
"ADC1 Invert Switch"
,
CS42XX8_ADCINV
,
0
,
1
,
1
,
0
),
SOC_DOUBLE
(
"ADC2 Invert Switch"
,
CS42XX8_ADCINV
,
2
,
3
,
1
,
0
),
SOC_SINGLE
(
"ADC High-Pass Filter Switch"
,
CS42XX8_ADCCTL
,
7
,
1
,
1
),
SOC_SINGLE
(
"DAC De-emphasis Switch"
,
CS42XX8_ADCCTL
,
5
,
1
,
0
),
SOC_ENUM
(
"ADC1 Single Ended Mode Switch"
,
adc1_single_enum
),
SOC_ENUM
(
"ADC2 Single Ended Mode Switch"
,
adc2_single_enum
),
SOC_SINGLE
(
"DAC Single Volume Control Switch"
,
CS42XX8_TXCTL
,
7
,
1
,
0
),
SOC_ENUM
(
"DAC Soft Ramp & Zero Cross Control Switch"
,
dac_szc_enum
),
SOC_SINGLE
(
"DAC Auto Mute Switch"
,
CS42XX8_TXCTL
,
4
,
1
,
0
),
SOC_SINGLE
(
"Mute ADC Serial Port Switch"
,
CS42XX8_TXCTL
,
3
,
1
,
0
),
SOC_SINGLE
(
"ADC Single Volume Control Switch"
,
CS42XX8_TXCTL
,
2
,
1
,
0
),
SOC_ENUM
(
"ADC Soft Ramp & Zero Cross Control Switch"
,
adc_szc_enum
),
};
static
const
struct
snd_kcontrol_new
cs42xx8_adc3_snd_controls
[]
=
{
SOC_DOUBLE_R_S_TLV
(
"ADC3 Capture Volume"
,
CS42XX8_VOLAIN5
,
CS42XX8_VOLAIN6
,
0
,
-
0x80
,
0x30
,
7
,
0
,
adc_tlv
),
SOC_DOUBLE
(
"ADC3 Invert Switch"
,
CS42XX8_ADCINV
,
4
,
5
,
1
,
0
),
SOC_ENUM
(
"ADC3 Single Ended Mode Switch"
,
adc3_single_enum
),
};
static
const
struct
snd_soc_dapm_widget
cs42xx8_dapm_widgets
[]
=
{
SND_SOC_DAPM_DAC
(
"DAC1"
,
"Playback"
,
CS42XX8_PWRCTL
,
1
,
1
),
SND_SOC_DAPM_DAC
(
"DAC2"
,
"Playback"
,
CS42XX8_PWRCTL
,
2
,
1
),
SND_SOC_DAPM_DAC
(
"DAC3"
,
"Playback"
,
CS42XX8_PWRCTL
,
3
,
1
),
SND_SOC_DAPM_DAC
(
"DAC4"
,
"Playback"
,
CS42XX8_PWRCTL
,
4
,
1
),
SND_SOC_DAPM_OUTPUT
(
"AOUT1L"
),
SND_SOC_DAPM_OUTPUT
(
"AOUT1R"
),
SND_SOC_DAPM_OUTPUT
(
"AOUT2L"
),
SND_SOC_DAPM_OUTPUT
(
"AOUT2R"
),
SND_SOC_DAPM_OUTPUT
(
"AOUT3L"
),
SND_SOC_DAPM_OUTPUT
(
"AOUT3R"
),
SND_SOC_DAPM_OUTPUT
(
"AOUT4L"
),
SND_SOC_DAPM_OUTPUT
(
"AOUT4R"
),
SND_SOC_DAPM_ADC
(
"ADC1"
,
"Capture"
,
CS42XX8_PWRCTL
,
5
,
1
),
SND_SOC_DAPM_ADC
(
"ADC2"
,
"Capture"
,
CS42XX8_PWRCTL
,
6
,
1
),
SND_SOC_DAPM_INPUT
(
"AIN1L"
),
SND_SOC_DAPM_INPUT
(
"AIN1R"
),
SND_SOC_DAPM_INPUT
(
"AIN2L"
),
SND_SOC_DAPM_INPUT
(
"AIN2R"
),
SND_SOC_DAPM_SUPPLY
(
"PWR"
,
CS42XX8_PWRCTL
,
0
,
1
,
NULL
,
0
),
};
static
const
struct
snd_soc_dapm_widget
cs42xx8_adc3_dapm_widgets
[]
=
{
SND_SOC_DAPM_ADC
(
"ADC3"
,
"Capture"
,
CS42XX8_PWRCTL
,
7
,
1
),
SND_SOC_DAPM_INPUT
(
"AIN3L"
),
SND_SOC_DAPM_INPUT
(
"AIN3R"
),
};
static
const
struct
snd_soc_dapm_route
cs42xx8_dapm_routes
[]
=
{
/* Playback */
{
"AOUT1L"
,
NULL
,
"DAC1"
},
{
"AOUT1R"
,
NULL
,
"DAC1"
},
{
"DAC1"
,
NULL
,
"PWR"
},
{
"AOUT2L"
,
NULL
,
"DAC2"
},
{
"AOUT2R"
,
NULL
,
"DAC2"
},
{
"DAC2"
,
NULL
,
"PWR"
},
{
"AOUT3L"
,
NULL
,
"DAC3"
},
{
"AOUT3R"
,
NULL
,
"DAC3"
},
{
"DAC3"
,
NULL
,
"PWR"
},
{
"AOUT4L"
,
NULL
,
"DAC4"
},
{
"AOUT4R"
,
NULL
,
"DAC4"
},
{
"DAC4"
,
NULL
,
"PWR"
},
/* Capture */
{
"ADC1"
,
NULL
,
"AIN1L"
},
{
"ADC1"
,
NULL
,
"AIN1R"
},
{
"ADC1"
,
NULL
,
"PWR"
},
{
"ADC2"
,
NULL
,
"AIN2L"
},
{
"ADC2"
,
NULL
,
"AIN2R"
},
{
"ADC2"
,
NULL
,
"PWR"
},
};
static
const
struct
snd_soc_dapm_route
cs42xx8_adc3_dapm_routes
[]
=
{
/* Capture */
{
"ADC3"
,
NULL
,
"AIN3L"
},
{
"ADC3"
,
NULL
,
"AIN3R"
},
{
"ADC3"
,
NULL
,
"PWR"
},
};
struct
cs42xx8_ratios
{
unsigned
int
ratio
;
unsigned
char
speed
;
unsigned
char
mclk
;
};
static
const
struct
cs42xx8_ratios
cs42xx8_ratios
[]
=
{
{
64
,
CS42XX8_FM_QUAD
,
CS42XX8_FUNCMOD_MFREQ_256
(
4
)
},
{
96
,
CS42XX8_FM_QUAD
,
CS42XX8_FUNCMOD_MFREQ_384
(
4
)
},
{
128
,
CS42XX8_FM_QUAD
,
CS42XX8_FUNCMOD_MFREQ_512
(
4
)
},
{
192
,
CS42XX8_FM_QUAD
,
CS42XX8_FUNCMOD_MFREQ_768
(
4
)
},
{
256
,
CS42XX8_FM_SINGLE
,
CS42XX8_FUNCMOD_MFREQ_256
(
1
)
},
{
384
,
CS42XX8_FM_SINGLE
,
CS42XX8_FUNCMOD_MFREQ_384
(
1
)
},
{
512
,
CS42XX8_FM_SINGLE
,
CS42XX8_FUNCMOD_MFREQ_512
(
1
)
},
{
768
,
CS42XX8_FM_SINGLE
,
CS42XX8_FUNCMOD_MFREQ_768
(
1
)
},
{
1024
,
CS42XX8_FM_SINGLE
,
CS42XX8_FUNCMOD_MFREQ_1024
(
1
)
}
};
static
int
cs42xx8_set_dai_sysclk
(
struct
snd_soc_dai
*
codec_dai
,
int
clk_id
,
unsigned
int
freq
,
int
dir
)
{
struct
snd_soc_codec
*
codec
=
codec_dai
->
codec
;
struct
cs42xx8_priv
*
cs42xx8
=
snd_soc_codec_get_drvdata
(
codec
);
cs42xx8
->
sysclk
=
freq
;
return
0
;
}
static
int
cs42xx8_set_dai_fmt
(
struct
snd_soc_dai
*
codec_dai
,
unsigned
int
format
)
{
struct
snd_soc_codec
*
codec
=
codec_dai
->
codec
;
struct
cs42xx8_priv
*
cs42xx8
=
snd_soc_codec_get_drvdata
(
codec
);
u32
val
;
/* Set DAI format */
switch
(
format
&
SND_SOC_DAIFMT_FORMAT_MASK
)
{
case
SND_SOC_DAIFMT_LEFT_J
:
val
=
CS42XX8_INTF_DAC_DIF_LEFTJ
|
CS42XX8_INTF_ADC_DIF_LEFTJ
;
break
;
case
SND_SOC_DAIFMT_I2S
:
val
=
CS42XX8_INTF_DAC_DIF_I2S
|
CS42XX8_INTF_ADC_DIF_I2S
;
break
;
case
SND_SOC_DAIFMT_RIGHT_J
:
val
=
CS42XX8_INTF_DAC_DIF_RIGHTJ
|
CS42XX8_INTF_ADC_DIF_RIGHTJ
;
break
;
default:
dev_err
(
codec
->
dev
,
"unsupported dai format
\n
"
);
return
-
EINVAL
;
}
regmap_update_bits
(
cs42xx8
->
regmap
,
CS42XX8_INTF
,
CS42XX8_INTF_DAC_DIF_MASK
|
CS42XX8_INTF_ADC_DIF_MASK
,
val
);
/* Set master/slave audio interface */
switch
(
format
&
SND_SOC_DAIFMT_MASTER_MASK
)
{
case
SND_SOC_DAIFMT_CBS_CFS
:
cs42xx8
->
slave_mode
=
true
;
break
;
case
SND_SOC_DAIFMT_CBM_CFM
:
cs42xx8
->
slave_mode
=
false
;
break
;
default:
dev_err
(
codec
->
dev
,
"unsupported master/slave mode
\n
"
);
return
-
EINVAL
;
}
return
0
;
}
static
int
cs42xx8_hw_params
(
struct
snd_pcm_substream
*
substream
,
struct
snd_pcm_hw_params
*
params
,
struct
snd_soc_dai
*
dai
)
{
struct
snd_soc_pcm_runtime
*
rtd
=
substream
->
private_data
;
struct
snd_soc_codec
*
codec
=
rtd
->
codec
;
struct
cs42xx8_priv
*
cs42xx8
=
snd_soc_codec_get_drvdata
(
codec
);
bool
tx
=
substream
->
stream
==
SNDRV_PCM_STREAM_PLAYBACK
;
u32
ratio
=
cs42xx8
->
sysclk
/
params_rate
(
params
);
u32
i
,
fm
,
val
,
mask
;
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
cs42xx8_ratios
);
i
++
)
{
if
(
cs42xx8_ratios
[
i
].
ratio
==
ratio
)
break
;
}
if
(
i
==
ARRAY_SIZE
(
cs42xx8_ratios
))
{
dev_err
(
codec
->
dev
,
"unsupported sysclk ratio
\n
"
);
return
-
EINVAL
;
}
mask
=
CS42XX8_FUNCMOD_MFREQ_MASK
;
val
=
cs42xx8_ratios
[
i
].
mclk
;
fm
=
cs42xx8
->
slave_mode
?
CS42XX8_FM_AUTO
:
cs42xx8_ratios
[
i
].
speed
;
regmap_update_bits
(
cs42xx8
->
regmap
,
CS42XX8_FUNCMOD
,
CS42XX8_FUNCMOD_xC_FM_MASK
(
tx
)
|
mask
,
CS42XX8_FUNCMOD_xC_FM
(
tx
,
fm
)
|
val
);
return
0
;
}
static
int
cs42xx8_digital_mute
(
struct
snd_soc_dai
*
dai
,
int
mute
)
{
struct
snd_soc_codec
*
codec
=
dai
->
codec
;
struct
cs42xx8_priv
*
cs42xx8
=
snd_soc_codec_get_drvdata
(
codec
);
regmap_update_bits
(
cs42xx8
->
regmap
,
CS42XX8_DACMUTE
,
CS42XX8_DACMUTE_ALL
,
mute
?
CS42XX8_DACMUTE_ALL
:
0
);
return
0
;
}
static
const
struct
snd_soc_dai_ops
cs42xx8_dai_ops
=
{
.
set_fmt
=
cs42xx8_set_dai_fmt
,
.
set_sysclk
=
cs42xx8_set_dai_sysclk
,
.
hw_params
=
cs42xx8_hw_params
,
.
digital_mute
=
cs42xx8_digital_mute
,
};
static
struct
snd_soc_dai_driver
cs42xx8_dai
=
{
.
playback
=
{
.
stream_name
=
"Playback"
,
.
channels_min
=
1
,
.
channels_max
=
8
,
.
rates
=
SNDRV_PCM_RATE_8000_192000
,
.
formats
=
CS42XX8_FORMATS
,
},
.
capture
=
{
.
stream_name
=
"Capture"
,
.
channels_min
=
1
,
.
rates
=
SNDRV_PCM_RATE_8000_192000
,
.
formats
=
CS42XX8_FORMATS
,
},
.
ops
=
&
cs42xx8_dai_ops
,
};
static
const
struct
reg_default
cs42xx8_reg
[]
=
{
{
0x01
,
0x01
},
/* Chip I.D. and Revision Register */
{
0x02
,
0x00
},
/* Power Control */
{
0x03
,
0xF0
},
/* Functional Mode */
{
0x04
,
0x46
},
/* Interface Formats */
{
0x05
,
0x00
},
/* ADC Control & DAC De-Emphasis */
{
0x06
,
0x10
},
/* Transition Control */
{
0x07
,
0x00
},
/* DAC Channel Mute */
{
0x08
,
0x00
},
/* Volume Control AOUT1 */
{
0x09
,
0x00
},
/* Volume Control AOUT2 */
{
0x0a
,
0x00
},
/* Volume Control AOUT3 */
{
0x0b
,
0x00
},
/* Volume Control AOUT4 */
{
0x0c
,
0x00
},
/* Volume Control AOUT5 */
{
0x0d
,
0x00
},
/* Volume Control AOUT6 */
{
0x0e
,
0x00
},
/* Volume Control AOUT7 */
{
0x0f
,
0x00
},
/* Volume Control AOUT8 */
{
0x10
,
0x00
},
/* DAC Channel Invert */
{
0x11
,
0x00
},
/* Volume Control AIN1 */
{
0x12
,
0x00
},
/* Volume Control AIN2 */
{
0x13
,
0x00
},
/* Volume Control AIN3 */
{
0x14
,
0x00
},
/* Volume Control AIN4 */
{
0x15
,
0x00
},
/* Volume Control AIN5 */
{
0x16
,
0x00
},
/* Volume Control AIN6 */
{
0x17
,
0x00
},
/* ADC Channel Invert */
{
0x18
,
0x00
},
/* Status Control */
{
0x1a
,
0x00
},
/* Status Mask */
{
0x1b
,
0x00
},
/* MUTEC Pin Control */
};
static
bool
cs42xx8_volatile_register
(
struct
device
*
dev
,
unsigned
int
reg
)
{
switch
(
reg
)
{
case
CS42XX8_STATUS
:
return
true
;
default:
return
false
;
}
}
static
bool
cs42xx8_writeable_register
(
struct
device
*
dev
,
unsigned
int
reg
)
{
switch
(
reg
)
{
case
CS42XX8_CHIPID
:
case
CS42XX8_STATUS
:
return
false
;
default:
return
true
;
}
}
const
struct
regmap_config
cs42xx8_regmap_config
=
{
.
reg_bits
=
8
,
.
val_bits
=
8
,
.
max_register
=
CS42XX8_LASTREG
,
.
reg_defaults
=
cs42xx8_reg
,
.
num_reg_defaults
=
ARRAY_SIZE
(
cs42xx8_reg
),
.
volatile_reg
=
cs42xx8_volatile_register
,
.
writeable_reg
=
cs42xx8_writeable_register
,
.
cache_type
=
REGCACHE_RBTREE
,
};
EXPORT_SYMBOL_GPL
(
cs42xx8_regmap_config
);
static
int
cs42xx8_codec_probe
(
struct
snd_soc_codec
*
codec
)
{
struct
cs42xx8_priv
*
cs42xx8
=
snd_soc_codec_get_drvdata
(
codec
);
struct
snd_soc_dapm_context
*
dapm
=
&
codec
->
dapm
;
switch
(
cs42xx8
->
drvdata
->
num_adcs
)
{
case
3
:
snd_soc_add_codec_controls
(
codec
,
cs42xx8_adc3_snd_controls
,
ARRAY_SIZE
(
cs42xx8_adc3_snd_controls
));
snd_soc_dapm_new_controls
(
dapm
,
cs42xx8_adc3_dapm_widgets
,
ARRAY_SIZE
(
cs42xx8_adc3_dapm_widgets
));
snd_soc_dapm_add_routes
(
dapm
,
cs42xx8_adc3_dapm_routes
,
ARRAY_SIZE
(
cs42xx8_adc3_dapm_routes
));
break
;
default:
break
;
}
/* Mute all DAC channels */
regmap_write
(
cs42xx8
->
regmap
,
CS42XX8_DACMUTE
,
CS42XX8_DACMUTE_ALL
);
return
0
;
}
static
const
struct
snd_soc_codec_driver
cs42xx8_driver
=
{
.
probe
=
cs42xx8_codec_probe
,
.
idle_bias_off
=
true
,
.
controls
=
cs42xx8_snd_controls
,
.
num_controls
=
ARRAY_SIZE
(
cs42xx8_snd_controls
),
.
dapm_widgets
=
cs42xx8_dapm_widgets
,
.
num_dapm_widgets
=
ARRAY_SIZE
(
cs42xx8_dapm_widgets
),
.
dapm_routes
=
cs42xx8_dapm_routes
,
.
num_dapm_routes
=
ARRAY_SIZE
(
cs42xx8_dapm_routes
),
};
const
struct
cs42xx8_driver_data
cs42448_data
=
{
.
name
=
"cs42448"
,
.
num_adcs
=
3
,
};
EXPORT_SYMBOL_GPL
(
cs42448_data
);
const
struct
cs42xx8_driver_data
cs42888_data
=
{
.
name
=
"cs42888"
,
.
num_adcs
=
2
,
};
EXPORT_SYMBOL_GPL
(
cs42888_data
);
const
struct
of_device_id
cs42xx8_of_match
[]
=
{
{
.
compatible
=
"cirrus,cs42448"
,
.
data
=
&
cs42448_data
,
},
{
.
compatible
=
"cirrus,cs42888"
,
.
data
=
&
cs42888_data
,
},
{
/* sentinel */
}
};
MODULE_DEVICE_TABLE
(
of
,
cs42xx8_of_match
);
EXPORT_SYMBOL_GPL
(
cs42xx8_of_match
);
int
cs42xx8_probe
(
struct
device
*
dev
,
struct
regmap
*
regmap
)
{
const
struct
of_device_id
*
of_id
=
of_match_device
(
cs42xx8_of_match
,
dev
);
struct
cs42xx8_priv
*
cs42xx8
;
int
ret
,
val
,
i
;
cs42xx8
=
devm_kzalloc
(
dev
,
sizeof
(
*
cs42xx8
),
GFP_KERNEL
);
if
(
cs42xx8
==
NULL
)
return
-
ENOMEM
;
dev_set_drvdata
(
dev
,
cs42xx8
);
if
(
of_id
)
cs42xx8
->
drvdata
=
of_id
->
data
;
if
(
!
cs42xx8
->
drvdata
)
{
dev_err
(
dev
,
"failed to find driver data
\n
"
);
return
-
EINVAL
;
}
cs42xx8
->
clk
=
devm_clk_get
(
dev
,
"mclk"
);
if
(
IS_ERR
(
cs42xx8
->
clk
))
{
dev_err
(
dev
,
"failed to get the clock: %ld
\n
"
,
PTR_ERR
(
cs42xx8
->
clk
));
return
-
EINVAL
;
}
cs42xx8
->
sysclk
=
clk_get_rate
(
cs42xx8
->
clk
);
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
cs42xx8
->
supplies
);
i
++
)
cs42xx8
->
supplies
[
i
].
supply
=
cs42xx8_supply_names
[
i
];
ret
=
devm_regulator_bulk_get
(
dev
,
ARRAY_SIZE
(
cs42xx8
->
supplies
),
cs42xx8
->
supplies
);
if
(
ret
)
{
dev_err
(
dev
,
"failed to request supplies: %d
\n
"
,
ret
);
return
ret
;
}
ret
=
regulator_bulk_enable
(
ARRAY_SIZE
(
cs42xx8
->
supplies
),
cs42xx8
->
supplies
);
if
(
ret
)
{
dev_err
(
dev
,
"failed to enable supplies: %d
\n
"
,
ret
);
return
ret
;
}
/* Make sure hardware reset done */
msleep
(
5
);
cs42xx8
->
regmap
=
regmap
;
if
(
IS_ERR
(
cs42xx8
->
regmap
))
{
ret
=
PTR_ERR
(
cs42xx8
->
regmap
);
dev_err
(
dev
,
"failed to allocate regmap: %d
\n
"
,
ret
);
goto
err_enable
;
}
/*
* We haven't marked the chip revision as volatile due to
* sharing a register with the right input volume; explicitly
* bypass the cache to read it.
*/
regcache_cache_bypass
(
cs42xx8
->
regmap
,
true
);
/* Validate the chip ID */
regmap_read
(
cs42xx8
->
regmap
,
CS42XX8_CHIPID
,
&
val
);
if
(
val
<
0
)
{
dev_err
(
dev
,
"failed to get device ID: %x"
,
val
);
ret
=
-
EINVAL
;
goto
err_enable
;
}
/* The top four bits of the chip ID should be 0000 */
if
((
val
&
CS42XX8_CHIPID_CHIP_ID_MASK
)
!=
0x00
)
{
dev_err
(
dev
,
"unmatched chip ID: %d
\n
"
,
val
&
CS42XX8_CHIPID_CHIP_ID_MASK
);
ret
=
-
EINVAL
;
goto
err_enable
;
}
dev_info
(
dev
,
"found device, revision %X
\n
"
,
val
&
CS42XX8_CHIPID_REV_ID_MASK
);
regcache_cache_bypass
(
cs42xx8
->
regmap
,
false
);
cs42xx8_dai
.
name
=
cs42xx8
->
drvdata
->
name
;
/* Each adc supports stereo input */
cs42xx8_dai
.
capture
.
channels_max
=
cs42xx8
->
drvdata
->
num_adcs
*
2
;
ret
=
snd_soc_register_codec
(
dev
,
&
cs42xx8_driver
,
&
cs42xx8_dai
,
1
);
if
(
ret
)
{
dev_err
(
dev
,
"failed to register codec:%d
\n
"
,
ret
);
goto
err_enable
;
}
regcache_cache_only
(
cs42xx8
->
regmap
,
true
);
err_enable:
regulator_bulk_disable
(
ARRAY_SIZE
(
cs42xx8
->
supplies
),
cs42xx8
->
supplies
);
return
ret
;
}
EXPORT_SYMBOL_GPL
(
cs42xx8_probe
);
#ifdef CONFIG_PM_RUNTIME
static
int
cs42xx8_runtime_resume
(
struct
device
*
dev
)
{
struct
cs42xx8_priv
*
cs42xx8
=
dev_get_drvdata
(
dev
);
int
ret
;
ret
=
clk_prepare_enable
(
cs42xx8
->
clk
);
if
(
ret
)
{
dev_err
(
dev
,
"failed to enable mclk: %d
\n
"
,
ret
);
return
ret
;
}
ret
=
regulator_bulk_enable
(
ARRAY_SIZE
(
cs42xx8
->
supplies
),
cs42xx8
->
supplies
);
if
(
ret
)
{
dev_err
(
dev
,
"failed to enable supplies: %d
\n
"
,
ret
);
goto
err_clk
;
}
/* Make sure hardware reset done */
msleep
(
5
);
regcache_cache_only
(
cs42xx8
->
regmap
,
false
);
ret
=
regcache_sync
(
cs42xx8
->
regmap
);
if
(
ret
)
{
dev_err
(
dev
,
"failed to sync regmap: %d
\n
"
,
ret
);
goto
err_bulk
;
}
return
0
;
err_bulk:
regulator_bulk_disable
(
ARRAY_SIZE
(
cs42xx8
->
supplies
),
cs42xx8
->
supplies
);
err_clk:
clk_disable_unprepare
(
cs42xx8
->
clk
);
return
ret
;
}
static
int
cs42xx8_runtime_suspend
(
struct
device
*
dev
)
{
struct
cs42xx8_priv
*
cs42xx8
=
dev_get_drvdata
(
dev
);
regcache_cache_only
(
cs42xx8
->
regmap
,
true
);
regulator_bulk_disable
(
ARRAY_SIZE
(
cs42xx8
->
supplies
),
cs42xx8
->
supplies
);
clk_disable_unprepare
(
cs42xx8
->
clk
);
return
0
;
}
#endif
const
struct
dev_pm_ops
cs42xx8_pm
=
{
SET_RUNTIME_PM_OPS
(
cs42xx8_runtime_suspend
,
cs42xx8_runtime_resume
,
NULL
)
};
EXPORT_SYMBOL_GPL
(
cs42xx8_pm
);
MODULE_DESCRIPTION
(
"Cirrus Logic CS42448/CS42888 ALSA SoC Codec Driver"
);
MODULE_AUTHOR
(
"Freescale Semiconductor, Inc."
);
MODULE_LICENSE
(
"GPL"
);
sound/soc/codecs/cs42xx8.h
0 → 100644
View file @
b4d032b3
/*
* cs42xx8.h - Cirrus Logic CS42448/CS42888 Audio CODEC driver header file
*
* Copyright (C) 2014 Freescale Semiconductor, Inc.
*
* Author: Nicolin Chen <Guangyu.Chen@freescale.com>
*
* This file is licensed under the terms of the GNU General Public License
* version 2. This program is licensed "as is" without any warranty of any
* kind, whether express or implied.
*/
#ifndef _CS42XX8_H
#define _CS42XX8_H
struct
cs42xx8_driver_data
{
char
name
[
32
];
int
num_adcs
;
};
extern
const
struct
dev_pm_ops
cs42xx8_pm
;
extern
const
struct
cs42xx8_driver_data
cs42448_data
;
extern
const
struct
cs42xx8_driver_data
cs42888_data
;
extern
const
struct
regmap_config
cs42xx8_regmap_config
;
int
cs42xx8_probe
(
struct
device
*
dev
,
struct
regmap
*
regmap
);
/* CS42888 register map */
#define CS42XX8_CHIPID 0x01
/* Chip ID */
#define CS42XX8_PWRCTL 0x02
/* Power Control */
#define CS42XX8_FUNCMOD 0x03
/* Functional Mode */
#define CS42XX8_INTF 0x04
/* Interface Formats */
#define CS42XX8_ADCCTL 0x05
/* ADC Control */
#define CS42XX8_TXCTL 0x06
/* Transition Control */
#define CS42XX8_DACMUTE 0x07
/* DAC Mute Control */
#define CS42XX8_VOLAOUT1 0x08
/* Volume Control AOUT1 */
#define CS42XX8_VOLAOUT2 0x09
/* Volume Control AOUT2 */
#define CS42XX8_VOLAOUT3 0x0A
/* Volume Control AOUT3 */
#define CS42XX8_VOLAOUT4 0x0B
/* Volume Control AOUT4 */
#define CS42XX8_VOLAOUT5 0x0C
/* Volume Control AOUT5 */
#define CS42XX8_VOLAOUT6 0x0D
/* Volume Control AOUT6 */
#define CS42XX8_VOLAOUT7 0x0E
/* Volume Control AOUT7 */
#define CS42XX8_VOLAOUT8 0x0F
/* Volume Control AOUT8 */
#define CS42XX8_DACINV 0x10
/* DAC Channel Invert */
#define CS42XX8_VOLAIN1 0x11
/* Volume Control AIN1 */
#define CS42XX8_VOLAIN2 0x12
/* Volume Control AIN2 */
#define CS42XX8_VOLAIN3 0x13
/* Volume Control AIN3 */
#define CS42XX8_VOLAIN4 0x14
/* Volume Control AIN4 */
#define CS42XX8_VOLAIN5 0x15
/* Volume Control AIN5 */
#define CS42XX8_VOLAIN6 0x16
/* Volume Control AIN6 */
#define CS42XX8_ADCINV 0x17
/* ADC Channel Invert */
#define CS42XX8_STATUSCTL 0x18
/* Status Control */
#define CS42XX8_STATUS 0x19
/* Status */
#define CS42XX8_STATUSM 0x1A
/* Status Mask */
#define CS42XX8_MUTEC 0x1B
/* MUTEC Pin Control */
#define CS42XX8_FIRSTREG CS42XX8_CHIPID
#define CS42XX8_LASTREG CS42XX8_MUTEC
#define CS42XX8_NUMREGS (CS42XX8_LASTREG - CS42XX8_FIRSTREG + 1)
#define CS42XX8_I2C_INCR 0x80
/* Chip I.D. and Revision Register (Address 01h) */
#define CS42XX8_CHIPID_CHIP_ID_MASK 0xF0
#define CS42XX8_CHIPID_REV_ID_MASK 0x0F
/* Power Control (Address 02h) */
#define CS42XX8_PWRCTL_PDN_ADC3_SHIFT 7
#define CS42XX8_PWRCTL_PDN_ADC3_MASK (1 << CS42XX8_PWRCTL_PDN_ADC3_SHIFT)
#define CS42XX8_PWRCTL_PDN_ADC3 (1 << CS42XX8_PWRCTL_PDN_ADC3_SHIFT)
#define CS42XX8_PWRCTL_PDN_ADC2_SHIFT 6
#define CS42XX8_PWRCTL_PDN_ADC2_MASK (1 << CS42XX8_PWRCTL_PDN_ADC2_SHIFT)
#define CS42XX8_PWRCTL_PDN_ADC2 (1 << CS42XX8_PWRCTL_PDN_ADC2_SHIFT)
#define CS42XX8_PWRCTL_PDN_ADC1_SHIFT 5
#define CS42XX8_PWRCTL_PDN_ADC1_MASK (1 << CS42XX8_PWRCTL_PDN_ADC1_SHIFT)
#define CS42XX8_PWRCTL_PDN_ADC1 (1 << CS42XX8_PWRCTL_PDN_ADC1_SHIFT)
#define CS42XX8_PWRCTL_PDN_DAC4_SHIFT 4
#define CS42XX8_PWRCTL_PDN_DAC4_MASK (1 << CS42XX8_PWRCTL_PDN_DAC4_SHIFT)
#define CS42XX8_PWRCTL_PDN_DAC4 (1 << CS42XX8_PWRCTL_PDN_DAC4_SHIFT)
#define CS42XX8_PWRCTL_PDN_DAC3_SHIFT 3
#define CS42XX8_PWRCTL_PDN_DAC3_MASK (1 << CS42XX8_PWRCTL_PDN_DAC3_SHIFT)
#define CS42XX8_PWRCTL_PDN_DAC3 (1 << CS42XX8_PWRCTL_PDN_DAC3_SHIFT)
#define CS42XX8_PWRCTL_PDN_DAC2_SHIFT 2
#define CS42XX8_PWRCTL_PDN_DAC2_MASK (1 << CS42XX8_PWRCTL_PDN_DAC2_SHIFT)
#define CS42XX8_PWRCTL_PDN_DAC2 (1 << CS42XX8_PWRCTL_PDN_DAC2_SHIFT)
#define CS42XX8_PWRCTL_PDN_DAC1_SHIFT 1
#define CS42XX8_PWRCTL_PDN_DAC1_MASK (1 << CS42XX8_PWRCTL_PDN_DAC1_SHIFT)
#define CS42XX8_PWRCTL_PDN_DAC1 (1 << CS42XX8_PWRCTL_PDN_DAC1_SHIFT)
#define CS42XX8_PWRCTL_PDN_SHIFT 0
#define CS42XX8_PWRCTL_PDN_MASK (1 << CS42XX8_PWRCTL_PDN_SHIFT)
#define CS42XX8_PWRCTL_PDN (1 << CS42XX8_PWRCTL_PDN_SHIFT)
/* Functional Mode (Address 03h) */
#define CS42XX8_FUNCMOD_DAC_FM_SHIFT 6
#define CS42XX8_FUNCMOD_DAC_FM_WIDTH 2
#define CS42XX8_FUNCMOD_DAC_FM_MASK (((1 << CS42XX8_FUNCMOD_DAC_FM_WIDTH) - 1) << CS42XX8_FUNCMOD_DAC_FM_SHIFT)
#define CS42XX8_FUNCMOD_DAC_FM(v) ((v) << CS42XX8_FUNCMOD_DAC_FM_SHIFT)
#define CS42XX8_FUNCMOD_ADC_FM_SHIFT 4
#define CS42XX8_FUNCMOD_ADC_FM_WIDTH 2
#define CS42XX8_FUNCMOD_ADC_FM_MASK (((1 << CS42XX8_FUNCMOD_ADC_FM_WIDTH) - 1) << CS42XX8_FUNCMOD_ADC_FM_SHIFT)
#define CS42XX8_FUNCMOD_ADC_FM(v) ((v) << CS42XX8_FUNCMOD_ADC_FM_SHIFT)
#define CS42XX8_FUNCMOD_xC_FM_MASK(x) ((x) ? CS42XX8_FUNCMOD_DAC_FM_MASK : CS42XX8_FUNCMOD_ADC_FM_MASK)
#define CS42XX8_FUNCMOD_xC_FM(x, v) ((x) ? CS42XX8_FUNCMOD_DAC_FM(v) : CS42XX8_FUNCMOD_ADC_FM(v))
#define CS42XX8_FUNCMOD_MFREQ_SHIFT 1
#define CS42XX8_FUNCMOD_MFREQ_WIDTH 3
#define CS42XX8_FUNCMOD_MFREQ_MASK (((1 << CS42XX8_FUNCMOD_MFREQ_WIDTH) - 1) << CS42XX8_FUNCMOD_MFREQ_SHIFT)
#define CS42XX8_FUNCMOD_MFREQ_256(s) ((0 << CS42XX8_FUNCMOD_MFREQ_SHIFT) >> (s >> 1))
#define CS42XX8_FUNCMOD_MFREQ_384(s) ((1 << CS42XX8_FUNCMOD_MFREQ_SHIFT) >> (s >> 1))
#define CS42XX8_FUNCMOD_MFREQ_512(s) ((2 << CS42XX8_FUNCMOD_MFREQ_SHIFT) >> (s >> 1))
#define CS42XX8_FUNCMOD_MFREQ_768(s) ((3 << CS42XX8_FUNCMOD_MFREQ_SHIFT) >> (s >> 1))
#define CS42XX8_FUNCMOD_MFREQ_1024(s) ((4 << CS42XX8_FUNCMOD_MFREQ_SHIFT) >> (s >> 1))
#define CS42XX8_FM_SINGLE 0
#define CS42XX8_FM_DOUBLE 1
#define CS42XX8_FM_QUAD 2
#define CS42XX8_FM_AUTO 3
/* Interface Formats (Address 04h) */
#define CS42XX8_INTF_FREEZE_SHIFT 7
#define CS42XX8_INTF_FREEZE_MASK (1 << CS42XX8_INTF_FREEZE_SHIFT)
#define CS42XX8_INTF_FREEZE (1 << CS42XX8_INTF_FREEZE_SHIFT)
#define CS42XX8_INTF_AUX_DIF_SHIFT 6
#define CS42XX8_INTF_AUX_DIF_MASK (1 << CS42XX8_INTF_AUX_DIF_SHIFT)
#define CS42XX8_INTF_AUX_DIF (1 << CS42XX8_INTF_AUX_DIF_SHIFT)
#define CS42XX8_INTF_DAC_DIF_SHIFT 3
#define CS42XX8_INTF_DAC_DIF_WIDTH 3
#define CS42XX8_INTF_DAC_DIF_MASK (((1 << CS42XX8_INTF_DAC_DIF_WIDTH) - 1) << CS42XX8_INTF_DAC_DIF_SHIFT)
#define CS42XX8_INTF_DAC_DIF_LEFTJ (0 << CS42XX8_INTF_DAC_DIF_SHIFT)
#define CS42XX8_INTF_DAC_DIF_I2S (1 << CS42XX8_INTF_DAC_DIF_SHIFT)
#define CS42XX8_INTF_DAC_DIF_RIGHTJ (2 << CS42XX8_INTF_DAC_DIF_SHIFT)
#define CS42XX8_INTF_DAC_DIF_RIGHTJ_16 (3 << CS42XX8_INTF_DAC_DIF_SHIFT)
#define CS42XX8_INTF_DAC_DIF_ONELINE_20 (4 << CS42XX8_INTF_DAC_DIF_SHIFT)
#define CS42XX8_INTF_DAC_DIF_ONELINE_24 (6 << CS42XX8_INTF_DAC_DIF_SHIFT)
#define CS42XX8_INTF_DAC_DIF_TDM (7 << CS42XX8_INTF_DAC_DIF_SHIFT)
#define CS42XX8_INTF_ADC_DIF_SHIFT 0
#define CS42XX8_INTF_ADC_DIF_WIDTH 3
#define CS42XX8_INTF_ADC_DIF_MASK (((1 << CS42XX8_INTF_ADC_DIF_WIDTH) - 1) << CS42XX8_INTF_ADC_DIF_SHIFT)
#define CS42XX8_INTF_ADC_DIF_LEFTJ (0 << CS42XX8_INTF_ADC_DIF_SHIFT)
#define CS42XX8_INTF_ADC_DIF_I2S (1 << CS42XX8_INTF_ADC_DIF_SHIFT)
#define CS42XX8_INTF_ADC_DIF_RIGHTJ (2 << CS42XX8_INTF_ADC_DIF_SHIFT)
#define CS42XX8_INTF_ADC_DIF_RIGHTJ_16 (3 << CS42XX8_INTF_ADC_DIF_SHIFT)
#define CS42XX8_INTF_ADC_DIF_ONELINE_20 (4 << CS42XX8_INTF_ADC_DIF_SHIFT)
#define CS42XX8_INTF_ADC_DIF_ONELINE_24 (6 << CS42XX8_INTF_ADC_DIF_SHIFT)
#define CS42XX8_INTF_ADC_DIF_TDM (7 << CS42XX8_INTF_ADC_DIF_SHIFT)
/* ADC Control & DAC De-Emphasis (Address 05h) */
#define CS42XX8_ADCCTL_ADC_HPF_FREEZE_SHIFT 7
#define CS42XX8_ADCCTL_ADC_HPF_FREEZE_MASK (1 << CS42XX8_ADCCTL_ADC_HPF_FREEZE_SHIFT)
#define CS42XX8_ADCCTL_ADC_HPF_FREEZE (1 << CS42XX8_ADCCTL_ADC_HPF_FREEZE_SHIFT)
#define CS42XX8_ADCCTL_DAC_DEM_SHIFT 5
#define CS42XX8_ADCCTL_DAC_DEM_MASK (1 << CS42XX8_ADCCTL_DAC_DEM_SHIFT)
#define CS42XX8_ADCCTL_DAC_DEM (1 << CS42XX8_ADCCTL_DAC_DEM_SHIFT)
#define CS42XX8_ADCCTL_ADC1_SINGLE_SHIFT 4
#define CS42XX8_ADCCTL_ADC1_SINGLE_MASK (1 << CS42XX8_ADCCTL_ADC1_SINGLE_SHIFT)
#define CS42XX8_ADCCTL_ADC1_SINGLE (1 << CS42XX8_ADCCTL_ADC1_SINGLE_SHIFT)
#define CS42XX8_ADCCTL_ADC2_SINGLE_SHIFT 3
#define CS42XX8_ADCCTL_ADC2_SINGLE_MASK (1 << CS42XX8_ADCCTL_ADC2_SINGLE_SHIFT)
#define CS42XX8_ADCCTL_ADC2_SINGLE (1 << CS42XX8_ADCCTL_ADC2_SINGLE_SHIFT)
#define CS42XX8_ADCCTL_ADC3_SINGLE_SHIFT 2
#define CS42XX8_ADCCTL_ADC3_SINGLE_MASK (1 << CS42XX8_ADCCTL_ADC3_SINGLE_SHIFT)
#define CS42XX8_ADCCTL_ADC3_SINGLE (1 << CS42XX8_ADCCTL_ADC3_SINGLE_SHIFT)
#define CS42XX8_ADCCTL_AIN5_MUX_SHIFT 1
#define CS42XX8_ADCCTL_AIN5_MUX_MASK (1 << CS42XX8_ADCCTL_AIN5_MUX_SHIFT)
#define CS42XX8_ADCCTL_AIN5_MUX (1 << CS42XX8_ADCCTL_AIN5_MUX_SHIFT)
#define CS42XX8_ADCCTL_AIN6_MUX_SHIFT 0
#define CS42XX8_ADCCTL_AIN6_MUX_MASK (1 << CS42XX8_ADCCTL_AIN6_MUX_SHIFT)
#define CS42XX8_ADCCTL_AIN6_MUX (1 << CS42XX8_ADCCTL_AIN6_MUX_SHIFT)
/* Transition Control (Address 06h) */
#define CS42XX8_TXCTL_DAC_SNGVOL_SHIFT 7
#define CS42XX8_TXCTL_DAC_SNGVOL_MASK (1 << CS42XX8_TXCTL_DAC_SNGVOL_SHIFT)
#define CS42XX8_TXCTL_DAC_SNGVOL (1 << CS42XX8_TXCTL_DAC_SNGVOL_SHIFT)
#define CS42XX8_TXCTL_DAC_SZC_SHIFT 5
#define CS42XX8_TXCTL_DAC_SZC_WIDTH 2
#define CS42XX8_TXCTL_DAC_SZC_MASK (((1 << CS42XX8_TXCTL_DAC_SZC_WIDTH) - 1) << CS42XX8_TXCTL_DAC_SZC_SHIFT)
#define CS42XX8_TXCTL_DAC_SZC_IC (0 << CS42XX8_TXCTL_DAC_SZC_SHIFT)
#define CS42XX8_TXCTL_DAC_SZC_ZC (1 << CS42XX8_TXCTL_DAC_SZC_SHIFT)
#define CS42XX8_TXCTL_DAC_SZC_SR (2 << CS42XX8_TXCTL_DAC_SZC_SHIFT)
#define CS42XX8_TXCTL_DAC_SZC_SRZC (3 << CS42XX8_TXCTL_DAC_SZC_SHIFT)
#define CS42XX8_TXCTL_AMUTE_SHIFT 4
#define CS42XX8_TXCTL_AMUTE_MASK (1 << CS42XX8_TXCTL_AMUTE_SHIFT)
#define CS42XX8_TXCTL_AMUTE (1 << CS42XX8_TXCTL_AMUTE_SHIFT)
#define CS42XX8_TXCTL_MUTE_ADC_SP_SHIFT 3
#define CS42XX8_TXCTL_MUTE_ADC_SP_MASK (1 << CS42XX8_TXCTL_MUTE_ADC_SP_SHIFT)
#define CS42XX8_TXCTL_MUTE_ADC_SP (1 << CS42XX8_TXCTL_MUTE_ADC_SP_SHIFT)
#define CS42XX8_TXCTL_ADC_SNGVOL_SHIFT 2
#define CS42XX8_TXCTL_ADC_SNGVOL_MASK (1 << CS42XX8_TXCTL_ADC_SNGVOL_SHIFT)
#define CS42XX8_TXCTL_ADC_SNGVOL (1 << CS42XX8_TXCTL_ADC_SNGVOL_SHIFT)
#define CS42XX8_TXCTL_ADC_SZC_SHIFT 0
#define CS42XX8_TXCTL_ADC_SZC_MASK (((1 << CS42XX8_TXCTL_ADC_SZC_WIDTH) - 1) << CS42XX8_TXCTL_ADC_SZC_SHIFT)
#define CS42XX8_TXCTL_ADC_SZC_IC (0 << CS42XX8_TXCTL_ADC_SZC_SHIFT)
#define CS42XX8_TXCTL_ADC_SZC_ZC (1 << CS42XX8_TXCTL_ADC_SZC_SHIFT)
#define CS42XX8_TXCTL_ADC_SZC_SR (2 << CS42XX8_TXCTL_ADC_SZC_SHIFT)
#define CS42XX8_TXCTL_ADC_SZC_SRZC (3 << CS42XX8_TXCTL_ADC_SZC_SHIFT)
/* DAC Channel Mute (Address 07h) */
#define CS42XX8_DACMUTE_AOUT(n) (0x1 << n)
#define CS42XX8_DACMUTE_ALL 0xff
/* Status Control (Address 18h)*/
#define CS42XX8_STATUSCTL_INI_SHIFT 2
#define CS42XX8_STATUSCTL_INI_WIDTH 2
#define CS42XX8_STATUSCTL_INI_MASK (((1 << CS42XX8_STATUSCTL_INI_WIDTH) - 1) << CS42XX8_STATUSCTL_INI_SHIFT)
#define CS42XX8_STATUSCTL_INT_ACTIVE_HIGH (0 << CS42XX8_STATUSCTL_INI_SHIFT)
#define CS42XX8_STATUSCTL_INT_ACTIVE_LOW (1 << CS42XX8_STATUSCTL_INI_SHIFT)
#define CS42XX8_STATUSCTL_INT_OPEN_DRAIN (2 << CS42XX8_STATUSCTL_INI_SHIFT)
/* Status (Address 19h)*/
#define CS42XX8_STATUS_DAC_CLK_ERR_SHIFT 4
#define CS42XX8_STATUS_DAC_CLK_ERR_MASK (1 << CS42XX8_STATUS_DAC_CLK_ERR_SHIFT)
#define CS42XX8_STATUS_ADC_CLK_ERR_SHIFT 3
#define CS42XX8_STATUS_ADC_CLK_ERR_MASK (1 << CS42XX8_STATUS_ADC_CLK_ERR_SHIFT)
#define CS42XX8_STATUS_ADC3_OVFL_SHIFT 2
#define CS42XX8_STATUS_ADC3_OVFL_MASK (1 << CS42XX8_STATUS_ADC3_OVFL_SHIFT)
#define CS42XX8_STATUS_ADC2_OVFL_SHIFT 1
#define CS42XX8_STATUS_ADC2_OVFL_MASK (1 << CS42XX8_STATUS_ADC2_OVFL_SHIFT)
#define CS42XX8_STATUS_ADC1_OVFL_SHIFT 0
#define CS42XX8_STATUS_ADC1_OVFL_MASK (1 << CS42XX8_STATUS_ADC1_OVFL_SHIFT)
/* Status Mask (Address 1Ah) */
#define CS42XX8_STATUS_DAC_CLK_ERR_M_SHIFT 4
#define CS42XX8_STATUS_DAC_CLK_ERR_M_MASK (1 << CS42XX8_STATUS_DAC_CLK_ERR_M_SHIFT)
#define CS42XX8_STATUS_ADC_CLK_ERR_M_SHIFT 3
#define CS42XX8_STATUS_ADC_CLK_ERR_M_MASK (1 << CS42XX8_STATUS_ADC_CLK_ERR_M_SHIFT)
#define CS42XX8_STATUS_ADC3_OVFL_M_SHIFT 2
#define CS42XX8_STATUS_ADC3_OVFL_M_MASK (1 << CS42XX8_STATUS_ADC3_OVFL_M_SHIFT)
#define CS42XX8_STATUS_ADC2_OVFL_M_SHIFT 1
#define CS42XX8_STATUS_ADC2_OVFL_M_MASK (1 << CS42XX8_STATUS_ADC2_OVFL_M_SHIFT)
#define CS42XX8_STATUS_ADC1_OVFL_M_SHIFT 0
#define CS42XX8_STATUS_ADC1_OVFL_M_MASK (1 << CS42XX8_STATUS_ADC1_OVFL_M_SHIFT)
/* MUTEC Pin Control (Address 1Bh) */
#define CS42XX8_MUTEC_MCPOLARITY_SHIFT 1
#define CS42XX8_MUTEC_MCPOLARITY_MASK (1 << CS42XX8_MUTEC_MCPOLARITY_SHIFT)
#define CS42XX8_MUTEC_MCPOLARITY_ACTIVE_LOW (0 << CS42XX8_MUTEC_MCPOLARITY_SHIFT)
#define CS42XX8_MUTEC_MCPOLARITY_ACTIVE_HIGH (1 << CS42XX8_MUTEC_MCPOLARITY_SHIFT)
#define CS42XX8_MUTEC_MUTEC_ACTIVE_SHIFT 0
#define CS42XX8_MUTEC_MUTEC_ACTIVE_MASK (1 << CS42XX8_MUTEC_MUTEC_ACTIVE_SHIFT)
#define CS42XX8_MUTEC_MUTEC_ACTIVE (1 << CS42XX8_MUTEC_MUTEC_ACTIVE_SHIFT)
#endif
/* _CS42XX8_H */
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