Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
cloud-kernel
提交
efad6eed
cloud-kernel
项目概览
openanolis
/
cloud-kernel
1 年多 前同步成功
通知
160
Star
36
Fork
7
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
10
列表
看板
标记
里程碑
合并请求
2
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
cloud-kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
10
Issue
10
列表
看板
标记
里程碑
合并请求
2
合并请求
2
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
efad6eed
编写于
2月 11, 2013
作者:
M
Mark Brown
浏览文件
操作
浏览文件
下载
差异文件
Merge remote-tracking branch 'asoc/topic/twl' into asoc-next
上级
b363bcaf
85becda6
变更
9
显示空白变更内容
内联
并排
Showing
9 changed file
with
313 addition
and
600 deletion
+313
-600
Documentation/devicetree/bindings/sound/omap-twl4030.txt
Documentation/devicetree/bindings/sound/omap-twl4030.txt
+46
-0
sound/soc/codecs/twl4030.c
sound/soc/codecs/twl4030.c
+50
-35
sound/soc/codecs/twl6040.c
sound/soc/codecs/twl6040.c
+9
-53
sound/soc/omap/Kconfig
sound/soc/omap/Kconfig
+2
-17
sound/soc/omap/Makefile
sound/soc/omap/Makefile
+0
-4
sound/soc/omap/omap-twl4030.c
sound/soc/omap/omap-twl4030.c
+202
-2
sound/soc/omap/omap3pandora.c
sound/soc/omap/omap3pandora.c
+4
-4
sound/soc/omap/sdp3430.c
sound/soc/omap/sdp3430.c
+0
-278
sound/soc/omap/zoom2.c
sound/soc/omap/zoom2.c
+0
-207
未找到文件。
Documentation/devicetree/bindings/sound/omap-twl4030.txt
浏览文件 @
efad6eed
...
...
@@ -6,6 +6,52 @@ Required properties:
- ti,mcbsp: phandle for the McBSP node
- ti,codec: phandle for the twl4030 audio node
Optional properties:
- ti,mcbsp-voice: phandle for the McBSP node connected to the voice port of twl
- ti, jack-det-gpio: Jack detect GPIO
- ti,audio-routing: List of connections between audio components.
Each entry is a pair of strings, the first being the connection's sink,
the second being the connection's source.
If the routing is not provided all possible connection will be available
Available audio endpoints for the audio-routing table:
Board connectors:
* Headset Stereophone
* Earpiece Spk
* Handsfree Spk
* Ext Spk
* Main Mic
* Sub Mic
* Headset Mic
* Carkit Mic
* Digital0 Mic
* Digital1 Mic
* Line In
twl4030 pins:
* HSOL
* HSOR
* EARPIECE
* HFL
* HFR
* PREDRIVEL
* PREDRIVER
* CARKITL
* CARKITR
* MAINMIC
* SUBMIC
* HSMIC
* DIGIMIC0
* DIGIMIC1
* CARKITMIC
* AUXL
* AUXR
* Headset Mic Bias
* Mic Bias 1 /* Used for Main Mic or Digimic0 */
* Mic Bias 2 /* Used for Sub Mic or Digimic1 */
Example:
sound {
...
...
sound/soc/codecs/twl4030.c
浏览文件 @
efad6eed
...
...
@@ -41,6 +41,11 @@
/* Register descriptions are here */
#include <linux/mfd/twl4030-audio.h>
/* TWL4030 PMBR1 Register */
#define TWL4030_PMBR1_REG 0x0D
/* TWL4030 PMBR1 Register GPIO6 mux bits */
#define TWL4030_GPIO6_PWM0_MUTE(value) ((value & 0x03) << 2)
/* Shadow register used by the audio driver */
#define TWL4030_REG_SW_SHADOW 0x4A
#define TWL4030_CACHEREGNUM (TWL4030_REG_SW_SHADOW + 1)
...
...
@@ -348,8 +353,8 @@ static void twl4030_init_chip(struct snd_soc_codec *codec)
pdata
=
twl4030_get_pdata
(
codec
);
if
(
pdata
&&
pdata
->
hs_extmute
&&
gpio_is_valid
(
pdata
->
hs_extmute_gpio
))
{
if
(
pdata
&&
pdata
->
hs_extmute
)
{
if
(
gpio_is_valid
(
pdata
->
hs_extmute_gpio
))
{
int
ret
;
if
(
!
pdata
->
hs_extmute_gpio
)
...
...
@@ -357,11 +362,24 @@ static void twl4030_init_chip(struct snd_soc_codec *codec)
"Extmute GPIO is 0 is this correct?
\n
"
);
ret
=
gpio_request_one
(
pdata
->
hs_extmute_gpio
,
GPIOF_OUT_INIT_LOW
,
"hs_extmute"
);
GPIOF_OUT_INIT_LOW
,
"hs_extmute"
);
if
(
ret
)
{
dev_err
(
codec
->
dev
,
"Failed to get hs_extmute GPIO
\n
"
);
dev_err
(
codec
->
dev
,
"Failed to get hs_extmute GPIO
\n
"
);
pdata
->
hs_extmute_gpio
=
-
1
;
}
}
else
{
u8
pin_mux
;
/* Set TWL4030 GPIO6 as EXTMUTE signal */
twl_i2c_read_u8
(
TWL4030_MODULE_INTBR
,
&
pin_mux
,
TWL4030_PMBR1_REG
);
pin_mux
&=
~
TWL4030_GPIO6_PWM0_MUTE
(
0x03
);
pin_mux
|=
TWL4030_GPIO6_PWM0_MUTE
(
0x02
);
twl_i2c_write_u8
(
TWL4030_MODULE_INTBR
,
pin_mux
,
TWL4030_PMBR1_REG
);
}
}
/* Check defaults, if instructed before anything else */
...
...
@@ -1306,6 +1324,9 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = {
SND_SOC_DAPM_DAC
(
"DAC Left2"
,
NULL
,
SND_SOC_NOPM
,
0
,
0
),
SND_SOC_DAPM_DAC
(
"DAC Voice"
,
NULL
,
SND_SOC_NOPM
,
0
,
0
),
SND_SOC_DAPM_AIF_IN
(
"VAIFIN"
,
"Voice Playback"
,
0
,
TWL4030_REG_VOICE_IF
,
6
,
0
),
/* Analog bypasses */
SND_SOC_DAPM_SWITCH
(
"Right1 Analog Loopback"
,
SND_SOC_NOPM
,
0
,
0
,
&
twl4030_dapm_abypassr1_control
),
...
...
@@ -1438,6 +1459,9 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = {
SND_SOC_DAPM_ADC
(
"ADC Virtual Left2"
,
NULL
,
SND_SOC_NOPM
,
0
,
0
),
SND_SOC_DAPM_ADC
(
"ADC Virtual Right2"
,
NULL
,
SND_SOC_NOPM
,
0
,
0
),
SND_SOC_DAPM_AIF_OUT
(
"VAIFOUT"
,
"Voice Capture"
,
0
,
TWL4030_REG_VOICE_IF
,
5
,
0
),
/* Analog/Digital mic path selection.
TX1 Left/Right: either analog Left/Right or Digimic0
TX2 Left/Right: either analog Left/Right or Digimic1 */
...
...
@@ -1473,10 +1497,15 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = {
SND_SOC_DAPM_SUPPLY
(
"micbias2 select"
,
TWL4030_REG_MICBIAS_CTL
,
6
,
0
,
NULL
,
0
),
SND_SOC_DAPM_MICBIAS
(
"Mic Bias 1"
,
TWL4030_REG_MICBIAS_CTL
,
0
,
0
),
SND_SOC_DAPM_MICBIAS
(
"Mic Bias 2"
,
TWL4030_REG_MICBIAS_CTL
,
1
,
0
),
SND_SOC_DAPM_MICBIAS
(
"Headset Mic Bias"
,
TWL4030_REG_MICBIAS_CTL
,
2
,
0
),
/* Microphone bias */
SND_SOC_DAPM_SUPPLY
(
"Mic Bias 1"
,
TWL4030_REG_MICBIAS_CTL
,
0
,
0
,
NULL
,
0
),
SND_SOC_DAPM_SUPPLY
(
"Mic Bias 2"
,
TWL4030_REG_MICBIAS_CTL
,
1
,
0
,
NULL
,
0
),
SND_SOC_DAPM_SUPPLY
(
"Headset Mic Bias"
,
TWL4030_REG_MICBIAS_CTL
,
2
,
0
,
NULL
,
0
),
SND_SOC_DAPM_SUPPLY
(
"VIF Enable"
,
TWL4030_REG_VOICE_IF
,
0
,
0
,
NULL
,
0
),
};
static
const
struct
snd_soc_dapm_route
intercon
[]
=
{
...
...
@@ -1485,17 +1514,16 @@ static const struct snd_soc_dapm_route intercon[] = {
{
"DAC Left1"
,
NULL
,
"HiFi Playback"
},
{
"DAC Right2"
,
NULL
,
"HiFi Playback"
},
{
"DAC Left2"
,
NULL
,
"HiFi Playback"
},
{
"DAC Voice"
,
NULL
,
"V
oice Playback
"
},
{
"DAC Voice"
,
NULL
,
"V
AIFIN
"
},
/* ADC -> Stream mapping */
{
"HiFi Capture"
,
NULL
,
"ADC Virtual Left1"
},
{
"HiFi Capture"
,
NULL
,
"ADC Virtual Right1"
},
{
"HiFi Capture"
,
NULL
,
"ADC Virtual Left2"
},
{
"HiFi Capture"
,
NULL
,
"ADC Virtual Right2"
},
{
"Voice Capture"
,
NULL
,
"ADC Virtual Left1"
},
{
"Voice Capture"
,
NULL
,
"ADC Virtual Right1"
},
{
"Voice Capture"
,
NULL
,
"ADC Virtual Left2"
},
{
"Voice Capture"
,
NULL
,
"ADC Virtual Right2"
},
{
"VAIFOUT"
,
NULL
,
"ADC Virtual Left2"
},
{
"VAIFOUT"
,
NULL
,
"ADC Virtual Right2"
},
{
"VAIFOUT"
,
NULL
,
"VIF Enable"
},
{
"Digital L1 Playback Mixer"
,
NULL
,
"DAC Left1"
},
{
"Digital R1 Playback Mixer"
,
NULL
,
"DAC Right1"
},
...
...
@@ -1510,6 +1538,7 @@ static const struct snd_soc_dapm_route intercon[] = {
{
"DAC Right1"
,
NULL
,
"AIF Enable"
},
{
"DAC Left2"
,
NULL
,
"AIF Enable"
},
{
"DAC Right1"
,
NULL
,
"AIF Enable"
},
{
"DAC Voice"
,
NULL
,
"VIF Enable"
},
{
"Digital R2 Playback Mixer"
,
NULL
,
"AIF Enable"
},
{
"Digital L2 Playback Mixer"
,
NULL
,
"AIF Enable"
},
...
...
@@ -2267,18 +2296,6 @@ static struct snd_soc_dai_driver twl4030_dai[] = {
},
};
static
int
twl4030_soc_suspend
(
struct
snd_soc_codec
*
codec
)
{
twl4030_set_bias_level
(
codec
,
SND_SOC_BIAS_OFF
);
return
0
;
}
static
int
twl4030_soc_resume
(
struct
snd_soc_codec
*
codec
)
{
twl4030_set_bias_level
(
codec
,
SND_SOC_BIAS_STANDBY
);
return
0
;
}
static
int
twl4030_soc_probe
(
struct
snd_soc_codec
*
codec
)
{
struct
twl4030_priv
*
twl4030
;
...
...
@@ -2316,8 +2333,6 @@ static int twl4030_soc_remove(struct snd_soc_codec *codec)
static
struct
snd_soc_codec_driver
soc_codec_dev_twl4030
=
{
.
probe
=
twl4030_soc_probe
,
.
remove
=
twl4030_soc_remove
,
.
suspend
=
twl4030_soc_suspend
,
.
resume
=
twl4030_soc_resume
,
.
read
=
twl4030_read_reg_cache
,
.
write
=
twl4030_write
,
.
set_bias_level
=
twl4030_set_bias_level
,
...
...
sound/soc/codecs/twl6040.c
浏览文件 @
efad6eed
...
...
@@ -69,13 +69,8 @@ struct twl6040_data {
int
hs_power_mode_locked
;
unsigned
int
clk_in
;
unsigned
int
sysclk
;
u16
hs_left_step
;
u16
hs_right_step
;
u16
hf_left_step
;
u16
hf_right_step
;
struct
twl6040_jack_data
hs_jack
;
struct
snd_soc_codec
*
codec
;
struct
workqueue_struct
*
workqueue
;
struct
mutex
mutex
;
};
...
...
@@ -404,8 +399,7 @@ static irqreturn_t twl6040_audio_handler(int irq, void *data)
struct
snd_soc_codec
*
codec
=
data
;
struct
twl6040_data
*
priv
=
snd_soc_codec_get_drvdata
(
codec
);
queue_delayed_work
(
priv
->
workqueue
,
&
priv
->
hs_jack
.
work
,
msecs_to_jiffies
(
200
));
schedule_delayed_work
(
&
priv
->
hs_jack
.
work
,
msecs_to_jiffies
(
200
));
return
IRQ_HANDLED
;
}
...
...
@@ -1115,7 +1109,6 @@ static int twl6040_suspend(struct snd_soc_codec *codec)
static
int
twl6040_resume
(
struct
snd_soc_codec
*
codec
)
{
twl6040_set_bias_level
(
codec
,
SND_SOC_BIAS_STANDBY
);
twl6040_set_bias_level
(
codec
,
codec
->
dapm
.
suspend_bias_level
);
return
0
;
}
...
...
@@ -1127,83 +1120,46 @@ static int twl6040_resume(struct snd_soc_codec *codec)
static
int
twl6040_probe
(
struct
snd_soc_codec
*
codec
)
{
struct
twl6040_data
*
priv
;
struct
twl6040_codec_data
*
pdata
=
dev_get_platdata
(
codec
->
dev
);
struct
platform_device
*
pdev
=
container_of
(
codec
->
dev
,
struct
platform_device
,
dev
);
int
ret
=
0
;
priv
=
kzalloc
(
sizeof
(
struct
twl6040_data
),
GFP_KERNEL
);
priv
=
devm_kzalloc
(
codec
->
dev
,
sizeof
(
*
priv
),
GFP_KERNEL
);
if
(
priv
==
NULL
)
return
-
ENOMEM
;
snd_soc_codec_set_drvdata
(
codec
,
priv
);
priv
->
codec
=
codec
;
codec
->
control_data
=
dev_get_drvdata
(
codec
->
dev
->
parent
);
if
(
pdata
&&
pdata
->
hs_left_step
&&
pdata
->
hs_right_step
)
{
priv
->
hs_left_step
=
pdata
->
hs_left_step
;
priv
->
hs_right_step
=
pdata
->
hs_right_step
;
}
else
{
priv
->
hs_left_step
=
1
;
priv
->
hs_right_step
=
1
;
}
if
(
pdata
&&
pdata
->
hf_left_step
&&
pdata
->
hf_right_step
)
{
priv
->
hf_left_step
=
pdata
->
hf_left_step
;
priv
->
hf_right_step
=
pdata
->
hf_right_step
;
}
else
{
priv
->
hf_left_step
=
1
;
priv
->
hf_right_step
=
1
;
}
priv
->
plug_irq
=
platform_get_irq
(
pdev
,
0
);
if
(
priv
->
plug_irq
<
0
)
{
dev_err
(
codec
->
dev
,
"invalid irq
\n
"
);
ret
=
-
EINVAL
;
goto
work_err
;
}
priv
->
workqueue
=
alloc_workqueue
(
"twl6040-codec"
,
0
,
0
);
if
(
!
priv
->
workqueue
)
{
ret
=
-
ENOMEM
;
goto
work_err
;
return
-
EINVAL
;
}
INIT_DELAYED_WORK
(
&
priv
->
hs_jack
.
work
,
twl6040_accessory_work
);
mutex_init
(
&
priv
->
mutex
);
ret
=
request_threaded_irq
(
priv
->
plug_irq
,
NULL
,
twl6040_audio_handler
,
0
,
"twl6040_irq_plug"
,
codec
);
ret
=
devm_request_threaded_irq
(
codec
->
dev
,
priv
->
plug_irq
,
NULL
,
twl6040_audio_handler
,
IRQF_NO_SUSPEND
,
"twl6040_irq_plug"
,
codec
);
if
(
ret
)
{
dev_err
(
codec
->
dev
,
"PLUG IRQ request failed: %d
\n
"
,
ret
);
goto
plugirq_err
;
return
ret
;
}
twl6040_init_chip
(
codec
);
/* power on device */
ret
=
twl6040_set_bias_level
(
codec
,
SND_SOC_BIAS_STANDBY
);
if
(
!
ret
)
return
0
;
/* Error path */
free_irq
(
priv
->
plug_irq
,
codec
);
plugirq_err:
destroy_workqueue
(
priv
->
workqueue
);
work_err:
kfree
(
priv
);
return
ret
;
return
twl6040_set_bias_level
(
codec
,
SND_SOC_BIAS_STANDBY
);
}
static
int
twl6040_remove
(
struct
snd_soc_codec
*
codec
)
{
struct
twl6040_data
*
priv
=
snd_soc_codec_get_drvdata
(
codec
);
twl6040_set_bias_level
(
codec
,
SND_SOC_BIAS_OFF
);
free_irq
(
priv
->
plug_irq
,
codec
);
destroy_workqueue
(
priv
->
workqueue
);
kfree
(
priv
);
return
0
;
}
...
...
sound/soc/omap/Kconfig
浏览文件 @
efad6eed
...
...
@@ -70,15 +70,6 @@ config SND_OMAP_SOC_AM3517EVM
Say Y if you want to add support for SoC audio on the OMAP3517 / AM3517
EVM.
config SND_OMAP_SOC_SDP3430
tristate "SoC Audio support for Texas Instruments SDP3430"
depends on TWL4030_CORE && SND_OMAP_SOC && MACH_OMAP_3430SDP
select SND_OMAP_SOC_MCBSP
select SND_SOC_TWL4030
help
Say Y if you want to add support for SoC audio on Texas Instruments
SDP3430.
config SND_OMAP_SOC_OMAP_TWL4030
tristate "SoC Audio support for TI SoC based boards with twl4030 codec"
depends on TWL4030_CORE && SND_OMAP_SOC
...
...
@@ -91,6 +82,8 @@ config SND_OMAP_SOC_OMAP_TWL4030
- Gumstix Overo or CompuLab CM-T35/CM-T3730
- IGEP v2
- OMAP3EVM
- SDP3430
- Zoom2
config SND_OMAP_SOC_OMAP_ABE_TWL6040
tristate "SoC Audio support for OMAP boards using ABE and twl6040 codec"
...
...
@@ -123,11 +116,3 @@ config SND_OMAP_SOC_OMAP3_PANDORA
select SND_SOC_TWL4030
help
Say Y if you want to add support for SoC audio on the OMAP3 Pandora.
config SND_OMAP_SOC_ZOOM2
tristate "SoC Audio support for Zoom2"
depends on TWL4030_CORE && SND_OMAP_SOC && MACH_OMAP_ZOOM2
select SND_OMAP_SOC_MCBSP
select SND_SOC_TWL4030
help
Say Y if you want to add support for Soc audio on Zoom2 board.
sound/soc/omap/Makefile
浏览文件 @
efad6eed
...
...
@@ -17,11 +17,9 @@ snd-soc-rx51-objs := rx51.o
snd-soc-ams-delta-objs
:=
ams-delta.o
snd-soc-osk5912-objs
:=
osk5912.o
snd-soc-am3517evm-objs
:=
am3517evm.o
snd-soc-sdp3430-objs
:=
sdp3430.o
snd-soc-omap-abe-twl6040-objs
:=
omap-abe-twl6040.o
snd-soc-omap-twl4030-objs
:=
omap-twl4030.o
snd-soc-omap3pandora-objs
:=
omap3pandora.o
snd-soc-zoom2-objs
:=
zoom2.o
snd-soc-omap-hdmi-card-objs
:=
omap-hdmi-card.o
obj-$(CONFIG_SND_OMAP_SOC_N810)
+=
snd-soc-n810.o
...
...
@@ -30,9 +28,7 @@ obj-$(CONFIG_SND_OMAP_SOC_AMS_DELTA) += snd-soc-ams-delta.o
obj-$(CONFIG_SND_OMAP_SOC_OSK5912)
+=
snd-soc-osk5912.o
obj-$(CONFIG_SND_OMAP_SOC_OMAP2EVM)
+=
snd-soc-omap2evm.o
obj-$(CONFIG_SND_OMAP_SOC_AM3517EVM)
+=
snd-soc-am3517evm.o
obj-$(CONFIG_SND_OMAP_SOC_SDP3430)
+=
snd-soc-sdp3430.o
obj-$(CONFIG_SND_OMAP_SOC_OMAP_ABE_TWL6040)
+=
snd-soc-omap-abe-twl6040.o
obj-$(CONFIG_SND_OMAP_SOC_OMAP_TWL4030)
+=
snd-soc-omap-twl4030.o
obj-$(CONFIG_SND_OMAP_SOC_OMAP3_PANDORA)
+=
snd-soc-omap3pandora.o
obj-$(CONFIG_SND_OMAP_SOC_ZOOM2)
+=
snd-soc-zoom2.o
obj-$(CONFIG_SND_OMAP_SOC_OMAP_HDMI)
+=
snd-soc-omap-hdmi-card.o
sound/soc/omap/omap-twl4030.c
浏览文件 @
efad6eed
...
...
@@ -11,6 +11,8 @@
* omap3evm (Author: Anuj Aggarwal <anuj.aggarwal@ti.com>)
* overo (Author: Steve Sakoman <steve@sakoman.com>)
* igep0020 (Author: Enric Balletbo i Serra <eballetbo@iseebcn.com>)
* zoom2 (Author: Misael Lopez Cruz <misael.lopez@ti.com>)
* sdp3430 (Author: Misael Lopez Cruz <misael.lopez@ti.com>)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
...
...
@@ -32,14 +34,22 @@
#include <linux/platform_data/omap-twl4030.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/gpio.h>
#include <linux/of_gpio.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/soc.h>
#include <sound/jack.h>
#include "omap-mcbsp.h"
#include "omap-pcm.h"
struct
omap_twl4030
{
int
jack_detect
;
/* board can detect jack events */
struct
snd_soc_jack
hs_jack
;
};
static
int
omap_twl4030_hw_params
(
struct
snd_pcm_substream
*
substream
,
struct
snd_pcm_hw_params
*
params
)
{
...
...
@@ -87,17 +97,164 @@ static struct snd_soc_ops omap_twl4030_ops = {
.
hw_params
=
omap_twl4030_hw_params
,
};
static
const
struct
snd_soc_dapm_widget
dapm_widgets
[]
=
{
SND_SOC_DAPM_SPK
(
"Earpiece Spk"
,
NULL
),
SND_SOC_DAPM_SPK
(
"Handsfree Spk"
,
NULL
),
SND_SOC_DAPM_HP
(
"Headset Stereophone"
,
NULL
),
SND_SOC_DAPM_SPK
(
"Ext Spk"
,
NULL
),
SND_SOC_DAPM_SPK
(
"Carkit Spk"
,
NULL
),
SND_SOC_DAPM_MIC
(
"Main Mic"
,
NULL
),
SND_SOC_DAPM_MIC
(
"Sub Mic"
,
NULL
),
SND_SOC_DAPM_MIC
(
"Headset Mic"
,
NULL
),
SND_SOC_DAPM_MIC
(
"Carkit Mic"
,
NULL
),
SND_SOC_DAPM_MIC
(
"Digital0 Mic"
,
NULL
),
SND_SOC_DAPM_MIC
(
"Digital1 Mic"
,
NULL
),
SND_SOC_DAPM_LINE
(
"Line In"
,
NULL
),
};
static
const
struct
snd_soc_dapm_route
audio_map
[]
=
{
/* Headset Stereophone: HSOL, HSOR */
{
"Headset Stereophone"
,
NULL
,
"HSOL"
},
{
"Headset Stereophone"
,
NULL
,
"HSOR"
},
/* External Speakers: HFL, HFR */
{
"Handsfree Spk"
,
NULL
,
"HFL"
},
{
"Handsfree Spk"
,
NULL
,
"HFR"
},
/* External Speakers: PredrivL, PredrivR */
{
"Ext Spk"
,
NULL
,
"PREDRIVEL"
},
{
"Ext Spk"
,
NULL
,
"PREDRIVER"
},
/* Carkit speakers: CARKITL, CARKITR */
{
"Carkit Spk"
,
NULL
,
"CARKITL"
},
{
"Carkit Spk"
,
NULL
,
"CARKITR"
},
/* Earpiece */
{
"Earpiece Spk"
,
NULL
,
"EARPIECE"
},
/* External Mics: MAINMIC, SUBMIC with bias */
{
"MAINMIC"
,
NULL
,
"Main Mic"
},
{
"Main Mic"
,
NULL
,
"Mic Bias 1"
},
{
"SUBMIC"
,
NULL
,
"Sub Mic"
},
{
"Sub Mic"
,
NULL
,
"Mic Bias 2"
},
/* Headset Mic: HSMIC with bias */
{
"HSMIC"
,
NULL
,
"Headset Mic"
},
{
"Headset Mic"
,
NULL
,
"Headset Mic Bias"
},
/* Digital Mics: DIGIMIC0, DIGIMIC1 with bias */
{
"DIGIMIC0"
,
NULL
,
"Digital0 Mic"
},
{
"Digital0 Mic"
,
NULL
,
"Mic Bias 1"
},
{
"DIGIMIC1"
,
NULL
,
"Digital1 Mic"
},
{
"Digital1 Mic"
,
NULL
,
"Mic Bias 2"
},
/* Carkit In: CARKITMIC */
{
"CARKITMIC"
,
NULL
,
"Carkit Mic"
},
/* Aux In: AUXL, AUXR */
{
"AUXL"
,
NULL
,
"Line In"
},
{
"AUXR"
,
NULL
,
"Line In"
},
};
/* Headset jack detection DAPM pins */
static
struct
snd_soc_jack_pin
hs_jack_pins
[]
=
{
{
.
pin
=
"Headset Mic"
,
.
mask
=
SND_JACK_MICROPHONE
,
},
{
.
pin
=
"Headset Stereophone"
,
.
mask
=
SND_JACK_HEADPHONE
,
},
};
/* Headset jack detection gpios */
static
struct
snd_soc_jack_gpio
hs_jack_gpios
[]
=
{
{
.
name
=
"hsdet-gpio"
,
.
report
=
SND_JACK_HEADSET
,
.
debounce_time
=
200
,
},
};
static
inline
void
twl4030_disconnect_pin
(
struct
snd_soc_dapm_context
*
dapm
,
int
connected
,
char
*
pin
)
{
if
(
!
connected
)
snd_soc_dapm_disable_pin
(
dapm
,
pin
);
}
static
int
omap_twl4030_init
(
struct
snd_soc_pcm_runtime
*
rtd
)
{
struct
snd_soc_codec
*
codec
=
rtd
->
codec
;
struct
snd_soc_card
*
card
=
codec
->
card
;
struct
snd_soc_dapm_context
*
dapm
=
&
codec
->
dapm
;
struct
omap_tw4030_pdata
*
pdata
=
dev_get_platdata
(
card
->
dev
);
struct
omap_twl4030
*
priv
=
snd_soc_card_get_drvdata
(
card
);
int
ret
=
0
;
/* Headset jack detection only if it is supported */
if
(
priv
->
jack_detect
>
0
)
{
hs_jack_gpios
[
0
].
gpio
=
priv
->
jack_detect
;
ret
=
snd_soc_jack_new
(
codec
,
"Headset Jack"
,
SND_JACK_HEADSET
,
&
priv
->
hs_jack
);
if
(
ret
)
return
ret
;
ret
=
snd_soc_jack_add_pins
(
&
priv
->
hs_jack
,
ARRAY_SIZE
(
hs_jack_pins
),
hs_jack_pins
);
if
(
ret
)
return
ret
;
ret
=
snd_soc_jack_add_gpios
(
&
priv
->
hs_jack
,
ARRAY_SIZE
(
hs_jack_gpios
),
hs_jack_gpios
);
if
(
ret
)
return
ret
;
}
/*
* NULL pdata means we booted with DT. In this case the routing is
* provided and the card is fully routed, no need to mark pins.
*/
if
(
!
pdata
||
!
pdata
->
custom_routing
)
return
ret
;
/* Disable not connected paths if not used */
twl4030_disconnect_pin
(
dapm
,
pdata
->
has_ear
,
"Earpiece Spk"
);
twl4030_disconnect_pin
(
dapm
,
pdata
->
has_hf
,
"Handsfree Spk"
);
twl4030_disconnect_pin
(
dapm
,
pdata
->
has_hs
,
"Headset Stereophone"
);
twl4030_disconnect_pin
(
dapm
,
pdata
->
has_predriv
,
"Ext Spk"
);
twl4030_disconnect_pin
(
dapm
,
pdata
->
has_carkit
,
"Carkit Spk"
);
twl4030_disconnect_pin
(
dapm
,
pdata
->
has_mainmic
,
"Main Mic"
);
twl4030_disconnect_pin
(
dapm
,
pdata
->
has_submic
,
"Sub Mic"
);
twl4030_disconnect_pin
(
dapm
,
pdata
->
has_hsmic
,
"Headset Mic"
);
twl4030_disconnect_pin
(
dapm
,
pdata
->
has_carkitmic
,
"Carkit Mic"
);
twl4030_disconnect_pin
(
dapm
,
pdata
->
has_digimic0
,
"Digital0 Mic"
);
twl4030_disconnect_pin
(
dapm
,
pdata
->
has_digimic1
,
"Digital1 Mic"
);
twl4030_disconnect_pin
(
dapm
,
pdata
->
has_linein
,
"Line In"
);
return
ret
;
}
/* Digital audio interface glue - connects codec <--> CPU */
static
struct
snd_soc_dai_link
omap_twl4030_dai_links
[]
=
{
{
.
name
=
"TWL4030"
,
.
stream_name
=
"TWL4030"
,
.
name
=
"TWL4030
HiFi
"
,
.
stream_name
=
"TWL4030
HiFi
"
,
.
cpu_dai_name
=
"omap-mcbsp.2"
,
.
codec_dai_name
=
"twl4030-hifi"
,
.
platform_name
=
"omap-pcm-audio"
,
.
codec_name
=
"twl4030-codec"
,
.
init
=
omap_twl4030_init
,
.
ops
=
&
omap_twl4030_ops
,
},
{
.
name
=
"TWL4030 Voice"
,
.
stream_name
=
"TWL4030 Voice"
,
.
cpu_dai_name
=
"omap-mcbsp.3"
,
.
codec_dai_name
=
"twl4030-voice"
,
.
platform_name
=
"omap-pcm-audio"
,
.
codec_name
=
"twl4030-codec"
,
.
dai_fmt
=
SND_SOC_DAIFMT_DSP_A
|
SND_SOC_DAIFMT_IB_NF
|
SND_SOC_DAIFMT_CBM_CFM
,
},
};
/* Audio machine driver */
...
...
@@ -105,6 +262,11 @@ static struct snd_soc_card omap_twl4030_card = {
.
owner
=
THIS_MODULE
,
.
dai_link
=
omap_twl4030_dai_links
,
.
num_links
=
ARRAY_SIZE
(
omap_twl4030_dai_links
),
.
dapm_widgets
=
dapm_widgets
,
.
num_dapm_widgets
=
ARRAY_SIZE
(
dapm_widgets
),
.
dapm_routes
=
audio_map
,
.
num_dapm_routes
=
ARRAY_SIZE
(
audio_map
),
};
static
int
omap_twl4030_probe
(
struct
platform_device
*
pdev
)
...
...
@@ -112,12 +274,18 @@ static int omap_twl4030_probe(struct platform_device *pdev)
struct
omap_tw4030_pdata
*
pdata
=
dev_get_platdata
(
&
pdev
->
dev
);
struct
device_node
*
node
=
pdev
->
dev
.
of_node
;
struct
snd_soc_card
*
card
=
&
omap_twl4030_card
;
struct
omap_twl4030
*
priv
;
int
ret
=
0
;
card
->
dev
=
&
pdev
->
dev
;
priv
=
devm_kzalloc
(
&
pdev
->
dev
,
sizeof
(
struct
omap_twl4030
),
GFP_KERNEL
);
if
(
priv
==
NULL
)
return
-
ENOMEM
;
if
(
node
)
{
struct
device_node
*
dai_node
;
struct
property
*
prop
;
if
(
snd_soc_of_parse_card_name
(
card
,
"ti,model"
))
{
dev_err
(
&
pdev
->
dev
,
"Card name is not provided
\n
"
);
...
...
@@ -132,6 +300,27 @@ static int omap_twl4030_probe(struct platform_device *pdev)
omap_twl4030_dai_links
[
0
].
cpu_dai_name
=
NULL
;
omap_twl4030_dai_links
[
0
].
cpu_of_node
=
dai_node
;
dai_node
=
of_parse_phandle
(
node
,
"ti,mcbsp-voice"
,
0
);
if
(
!
dai_node
)
{
card
->
num_links
=
1
;
}
else
{
omap_twl4030_dai_links
[
1
].
cpu_dai_name
=
NULL
;
omap_twl4030_dai_links
[
1
].
cpu_of_node
=
dai_node
;
}
priv
->
jack_detect
=
of_get_named_gpio
(
node
,
"ti,jack-det-gpio"
,
0
);
/* Optional: audio routing can be provided */
prop
=
of_find_property
(
node
,
"ti,audio-routing"
,
NULL
);
if
(
prop
)
{
ret
=
snd_soc_of_parse_audio_routing
(
card
,
"ti,audio-routing"
);
if
(
ret
)
return
ret
;
card
->
fully_routed
=
1
;
}
}
else
if
(
pdata
)
{
if
(
pdata
->
card_name
)
{
card
->
name
=
pdata
->
card_name
;
...
...
@@ -139,11 +328,17 @@ static int omap_twl4030_probe(struct platform_device *pdev)
dev_err
(
&
pdev
->
dev
,
"Card name is not provided
\n
"
);
return
-
ENODEV
;
}
if
(
!
pdata
->
voice_connected
)
card
->
num_links
=
1
;
priv
->
jack_detect
=
pdata
->
jack_detect
;
}
else
{
dev_err
(
&
pdev
->
dev
,
"Missing pdata
\n
"
);
return
-
ENODEV
;
}
snd_soc_card_set_drvdata
(
card
,
priv
);
ret
=
snd_soc_register_card
(
card
);
if
(
ret
)
{
dev_err
(
&
pdev
->
dev
,
"snd_soc_register_card() failed: %d
\n
"
,
...
...
@@ -157,7 +352,12 @@ static int omap_twl4030_probe(struct platform_device *pdev)
static
int
omap_twl4030_remove
(
struct
platform_device
*
pdev
)
{
struct
snd_soc_card
*
card
=
platform_get_drvdata
(
pdev
);
struct
omap_twl4030
*
priv
=
snd_soc_card_get_drvdata
(
card
);
if
(
priv
->
jack_detect
>
0
)
snd_soc_jack_free_gpios
(
&
priv
->
hs_jack
,
ARRAY_SIZE
(
hs_jack_gpios
),
hs_jack_gpios
);
snd_soc_unregister_card
(
card
);
return
0
;
...
...
sound/soc/omap/omap3pandora.c
浏览文件 @
efad6eed
...
...
@@ -144,11 +144,11 @@ static const struct snd_soc_dapm_route omap3pandora_in_map[] = {
{
"AUXL"
,
NULL
,
"Line In"
},
{
"AUXR"
,
NULL
,
"Line In"
},
{
"MAINMIC"
,
NULL
,
"Mic
Bias 1
"
},
{
"Mic
Bias 1"
,
NULL
,
"Mic (internal)
"
},
{
"MAINMIC"
,
NULL
,
"Mic
(internal)
"
},
{
"Mic
(internal)"
,
NULL
,
"Mic Bias 1
"
},
{
"SUBMIC"
,
NULL
,
"Mic
Bias 2
"
},
{
"Mic
Bias 2"
,
NULL
,
"Mic (external)
"
},
{
"SUBMIC"
,
NULL
,
"Mic
(external)
"
},
{
"Mic
(external)"
,
NULL
,
"Mic Bias 2
"
},
};
static
int
omap3pandora_out_init
(
struct
snd_soc_pcm_runtime
*
rtd
)
...
...
sound/soc/omap/sdp3430.c
已删除
100644 → 0
浏览文件 @
b363bcaf
/*
* sdp3430.c -- SoC audio for TI OMAP3430 SDP
*
* Author: Misael Lopez Cruz <x0052729@ti.com>
*
* Based on:
* Author: Steve Sakoman <steve@sakoman.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA
*
*/
#include <linux/clk.h>
#include <linux/platform_device.h>
#include <linux/i2c/twl.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/soc.h>
#include <sound/jack.h>
#include <asm/mach-types.h>
#include <linux/platform_data/gpio-omap.h>
#include <linux/platform_data/asoc-ti-mcbsp.h>
/* Register descriptions for twl4030 codec part */
#include <linux/mfd/twl4030-audio.h>
#include <linux/module.h>
#include "omap-mcbsp.h"
#include "omap-pcm.h"
/* TWL4030 PMBR1 Register */
#define TWL4030_INTBR_PMBR1 0x0D
/* TWL4030 PMBR1 Register GPIO6 mux bit */
#define TWL4030_GPIO6_PWM0_MUTE(value) (value << 2)
static
struct
snd_soc_card
snd_soc_sdp3430
;
static
int
sdp3430_hw_params
(
struct
snd_pcm_substream
*
substream
,
struct
snd_pcm_hw_params
*
params
)
{
struct
snd_soc_pcm_runtime
*
rtd
=
substream
->
private_data
;
struct
snd_soc_dai
*
codec_dai
=
rtd
->
codec_dai
;
int
ret
;
/* Set the codec system clock for DAC and ADC */
ret
=
snd_soc_dai_set_sysclk
(
codec_dai
,
0
,
26000000
,
SND_SOC_CLOCK_IN
);
if
(
ret
<
0
)
{
printk
(
KERN_ERR
"can't set codec system clock
\n
"
);
return
ret
;
}
return
0
;
}
static
struct
snd_soc_ops
sdp3430_ops
=
{
.
hw_params
=
sdp3430_hw_params
,
};
/* Headset jack */
static
struct
snd_soc_jack
hs_jack
;
/* Headset jack detection DAPM pins */
static
struct
snd_soc_jack_pin
hs_jack_pins
[]
=
{
{
.
pin
=
"Headset Mic"
,
.
mask
=
SND_JACK_MICROPHONE
,
},
{
.
pin
=
"Headset Stereophone"
,
.
mask
=
SND_JACK_HEADPHONE
,
},
};
/* Headset jack detection gpios */
static
struct
snd_soc_jack_gpio
hs_jack_gpios
[]
=
{
{
.
gpio
=
(
OMAP_MAX_GPIO_LINES
+
2
),
.
name
=
"hsdet-gpio"
,
.
report
=
SND_JACK_HEADSET
,
.
debounce_time
=
200
,
},
};
/* SDP3430 machine DAPM */
static
const
struct
snd_soc_dapm_widget
sdp3430_twl4030_dapm_widgets
[]
=
{
SND_SOC_DAPM_MIC
(
"Ext Mic"
,
NULL
),
SND_SOC_DAPM_SPK
(
"Ext Spk"
,
NULL
),
SND_SOC_DAPM_MIC
(
"Headset Mic"
,
NULL
),
SND_SOC_DAPM_HP
(
"Headset Stereophone"
,
NULL
),
};
static
const
struct
snd_soc_dapm_route
audio_map
[]
=
{
/* External Mics: MAINMIC, SUBMIC with bias*/
{
"MAINMIC"
,
NULL
,
"Mic Bias 1"
},
{
"SUBMIC"
,
NULL
,
"Mic Bias 2"
},
{
"Mic Bias 1"
,
NULL
,
"Ext Mic"
},
{
"Mic Bias 2"
,
NULL
,
"Ext Mic"
},
/* External Speakers: HFL, HFR */
{
"Ext Spk"
,
NULL
,
"HFL"
},
{
"Ext Spk"
,
NULL
,
"HFR"
},
/* Headset Mic: HSMIC with bias */
{
"HSMIC"
,
NULL
,
"Headset Mic Bias"
},
{
"Headset Mic Bias"
,
NULL
,
"Headset Mic"
},
/* Headset Stereophone (Headphone): HSOL, HSOR */
{
"Headset Stereophone"
,
NULL
,
"HSOL"
},
{
"Headset Stereophone"
,
NULL
,
"HSOR"
},
};
static
int
sdp3430_twl4030_init
(
struct
snd_soc_pcm_runtime
*
rtd
)
{
struct
snd_soc_codec
*
codec
=
rtd
->
codec
;
struct
snd_soc_dapm_context
*
dapm
=
&
codec
->
dapm
;
int
ret
;
/* SDP3430 connected pins */
snd_soc_dapm_enable_pin
(
dapm
,
"Ext Mic"
);
snd_soc_dapm_enable_pin
(
dapm
,
"Ext Spk"
);
snd_soc_dapm_disable_pin
(
dapm
,
"Headset Mic"
);
snd_soc_dapm_disable_pin
(
dapm
,
"Headset Stereophone"
);
/* TWL4030 not connected pins */
snd_soc_dapm_nc_pin
(
dapm
,
"AUXL"
);
snd_soc_dapm_nc_pin
(
dapm
,
"AUXR"
);
snd_soc_dapm_nc_pin
(
dapm
,
"CARKITMIC"
);
snd_soc_dapm_nc_pin
(
dapm
,
"DIGIMIC0"
);
snd_soc_dapm_nc_pin
(
dapm
,
"DIGIMIC1"
);
snd_soc_dapm_nc_pin
(
dapm
,
"OUTL"
);
snd_soc_dapm_nc_pin
(
dapm
,
"OUTR"
);
snd_soc_dapm_nc_pin
(
dapm
,
"EARPIECE"
);
snd_soc_dapm_nc_pin
(
dapm
,
"PREDRIVEL"
);
snd_soc_dapm_nc_pin
(
dapm
,
"PREDRIVER"
);
snd_soc_dapm_nc_pin
(
dapm
,
"CARKITL"
);
snd_soc_dapm_nc_pin
(
dapm
,
"CARKITR"
);
/* Headset jack detection */
ret
=
snd_soc_jack_new
(
codec
,
"Headset Jack"
,
SND_JACK_HEADSET
,
&
hs_jack
);
if
(
ret
)
return
ret
;
ret
=
snd_soc_jack_add_pins
(
&
hs_jack
,
ARRAY_SIZE
(
hs_jack_pins
),
hs_jack_pins
);
if
(
ret
)
return
ret
;
ret
=
snd_soc_jack_add_gpios
(
&
hs_jack
,
ARRAY_SIZE
(
hs_jack_gpios
),
hs_jack_gpios
);
return
ret
;
}
static
int
sdp3430_twl4030_voice_init
(
struct
snd_soc_pcm_runtime
*
rtd
)
{
struct
snd_soc_codec
*
codec
=
rtd
->
codec
;
unsigned
short
reg
;
/* Enable voice interface */
reg
=
codec
->
driver
->
read
(
codec
,
TWL4030_REG_VOICE_IF
);
reg
|=
TWL4030_VIF_DIN_EN
|
TWL4030_VIF_DOUT_EN
|
TWL4030_VIF_EN
;
codec
->
driver
->
write
(
codec
,
TWL4030_REG_VOICE_IF
,
reg
);
return
0
;
}
/* Digital audio interface glue - connects codec <--> CPU */
static
struct
snd_soc_dai_link
sdp3430_dai
[]
=
{
{
.
name
=
"TWL4030 I2S"
,
.
stream_name
=
"TWL4030 Audio"
,
.
cpu_dai_name
=
"omap-mcbsp.2"
,
.
codec_dai_name
=
"twl4030-hifi"
,
.
platform_name
=
"omap-pcm-audio"
,
.
codec_name
=
"twl4030-codec"
,
.
dai_fmt
=
SND_SOC_DAIFMT_I2S
|
SND_SOC_DAIFMT_NB_NF
|
SND_SOC_DAIFMT_CBM_CFM
,
.
init
=
sdp3430_twl4030_init
,
.
ops
=
&
sdp3430_ops
,
},
{
.
name
=
"TWL4030 PCM"
,
.
stream_name
=
"TWL4030 Voice"
,
.
cpu_dai_name
=
"omap-mcbsp.3"
,
.
codec_dai_name
=
"twl4030-voice"
,
.
platform_name
=
"omap-pcm-audio"
,
.
codec_name
=
"twl4030-codec"
,
.
dai_fmt
=
SND_SOC_DAIFMT_DSP_A
|
SND_SOC_DAIFMT_IB_NF
|
SND_SOC_DAIFMT_CBM_CFM
,
.
init
=
sdp3430_twl4030_voice_init
,
.
ops
=
&
sdp3430_ops
,
},
};
/* Audio machine driver */
static
struct
snd_soc_card
snd_soc_sdp3430
=
{
.
name
=
"SDP3430"
,
.
owner
=
THIS_MODULE
,
.
dai_link
=
sdp3430_dai
,
.
num_links
=
ARRAY_SIZE
(
sdp3430_dai
),
.
dapm_widgets
=
sdp3430_twl4030_dapm_widgets
,
.
num_dapm_widgets
=
ARRAY_SIZE
(
sdp3430_twl4030_dapm_widgets
),
.
dapm_routes
=
audio_map
,
.
num_dapm_routes
=
ARRAY_SIZE
(
audio_map
),
};
static
struct
platform_device
*
sdp3430_snd_device
;
static
int
__init
sdp3430_soc_init
(
void
)
{
int
ret
;
u8
pin_mux
;
if
(
!
machine_is_omap_3430sdp
())
return
-
ENODEV
;
printk
(
KERN_INFO
"SDP3430 SoC init
\n
"
);
sdp3430_snd_device
=
platform_device_alloc
(
"soc-audio"
,
-
1
);
if
(
!
sdp3430_snd_device
)
{
printk
(
KERN_ERR
"Platform device allocation failed
\n
"
);
return
-
ENOMEM
;
}
platform_set_drvdata
(
sdp3430_snd_device
,
&
snd_soc_sdp3430
);
/* Set TWL4030 GPIO6 as EXTMUTE signal */
twl_i2c_read_u8
(
TWL4030_MODULE_INTBR
,
&
pin_mux
,
TWL4030_INTBR_PMBR1
);
pin_mux
&=
~
TWL4030_GPIO6_PWM0_MUTE
(
0x03
);
pin_mux
|=
TWL4030_GPIO6_PWM0_MUTE
(
0x02
);
twl_i2c_write_u8
(
TWL4030_MODULE_INTBR
,
pin_mux
,
TWL4030_INTBR_PMBR1
);
ret
=
platform_device_add
(
sdp3430_snd_device
);
if
(
ret
)
goto
err1
;
return
0
;
err1:
printk
(
KERN_ERR
"Unable to add platform device
\n
"
);
platform_device_put
(
sdp3430_snd_device
);
return
ret
;
}
module_init
(
sdp3430_soc_init
);
static
void
__exit
sdp3430_soc_exit
(
void
)
{
snd_soc_jack_free_gpios
(
&
hs_jack
,
ARRAY_SIZE
(
hs_jack_gpios
),
hs_jack_gpios
);
platform_device_unregister
(
sdp3430_snd_device
);
}
module_exit
(
sdp3430_soc_exit
);
MODULE_AUTHOR
(
"Misael Lopez Cruz <x0052729@ti.com>"
);
MODULE_DESCRIPTION
(
"ALSA SoC SDP3430"
);
MODULE_LICENSE
(
"GPL"
);
sound/soc/omap/zoom2.c
已删除
100644 → 0
浏览文件 @
b363bcaf
/*
* zoom2.c -- SoC audio for Zoom2
*
* Author: Misael Lopez Cruz <x0052729@ti.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA
*
*/
#include <linux/clk.h>
#include <linux/platform_device.h>
#include <linux/gpio.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/soc.h>
#include <asm/mach-types.h>
#include <linux/platform_data/asoc-ti-mcbsp.h>
#include <linux/platform_data/gpio-omap.h>
/* Register descriptions for twl4030 codec part */
#include <linux/mfd/twl4030-audio.h>
#include <linux/module.h>
#include "omap-mcbsp.h"
#include "omap-pcm.h"
static
int
zoom2_hw_params
(
struct
snd_pcm_substream
*
substream
,
struct
snd_pcm_hw_params
*
params
)
{
struct
snd_soc_pcm_runtime
*
rtd
=
substream
->
private_data
;
struct
snd_soc_dai
*
codec_dai
=
rtd
->
codec_dai
;
int
ret
;
/* Set the codec system clock for DAC and ADC */
ret
=
snd_soc_dai_set_sysclk
(
codec_dai
,
0
,
26000000
,
SND_SOC_CLOCK_IN
);
if
(
ret
<
0
)
{
printk
(
KERN_ERR
"can't set codec system clock
\n
"
);
return
ret
;
}
return
0
;
}
static
struct
snd_soc_ops
zoom2_ops
=
{
.
hw_params
=
zoom2_hw_params
,
};
/* Zoom2 machine DAPM */
static
const
struct
snd_soc_dapm_widget
zoom2_twl4030_dapm_widgets
[]
=
{
SND_SOC_DAPM_MIC
(
"Ext Mic"
,
NULL
),
SND_SOC_DAPM_SPK
(
"Ext Spk"
,
NULL
),
SND_SOC_DAPM_MIC
(
"Headset Mic"
,
NULL
),
SND_SOC_DAPM_HP
(
"Headset Stereophone"
,
NULL
),
SND_SOC_DAPM_LINE
(
"Aux In"
,
NULL
),
};
static
const
struct
snd_soc_dapm_route
audio_map
[]
=
{
/* External Mics: MAINMIC, SUBMIC with bias*/
{
"MAINMIC"
,
NULL
,
"Mic Bias 1"
},
{
"SUBMIC"
,
NULL
,
"Mic Bias 2"
},
{
"Mic Bias 1"
,
NULL
,
"Ext Mic"
},
{
"Mic Bias 2"
,
NULL
,
"Ext Mic"
},
/* External Speakers: HFL, HFR */
{
"Ext Spk"
,
NULL
,
"HFL"
},
{
"Ext Spk"
,
NULL
,
"HFR"
},
/* Headset Stereophone: HSOL, HSOR */
{
"Headset Stereophone"
,
NULL
,
"HSOL"
},
{
"Headset Stereophone"
,
NULL
,
"HSOR"
},
/* Headset Mic: HSMIC with bias */
{
"HSMIC"
,
NULL
,
"Headset Mic Bias"
},
{
"Headset Mic Bias"
,
NULL
,
"Headset Mic"
},
/* Aux In: AUXL, AUXR */
{
"Aux In"
,
NULL
,
"AUXL"
},
{
"Aux In"
,
NULL
,
"AUXR"
},
};
static
int
zoom2_twl4030_init
(
struct
snd_soc_pcm_runtime
*
rtd
)
{
struct
snd_soc_codec
*
codec
=
rtd
->
codec
;
struct
snd_soc_dapm_context
*
dapm
=
&
codec
->
dapm
;
/* TWL4030 not connected pins */
snd_soc_dapm_nc_pin
(
dapm
,
"CARKITMIC"
);
snd_soc_dapm_nc_pin
(
dapm
,
"DIGIMIC0"
);
snd_soc_dapm_nc_pin
(
dapm
,
"DIGIMIC1"
);
snd_soc_dapm_nc_pin
(
dapm
,
"EARPIECE"
);
snd_soc_dapm_nc_pin
(
dapm
,
"PREDRIVEL"
);
snd_soc_dapm_nc_pin
(
dapm
,
"PREDRIVER"
);
snd_soc_dapm_nc_pin
(
dapm
,
"CARKITL"
);
snd_soc_dapm_nc_pin
(
dapm
,
"CARKITR"
);
return
0
;
}
static
int
zoom2_twl4030_voice_init
(
struct
snd_soc_pcm_runtime
*
rtd
)
{
struct
snd_soc_codec
*
codec
=
rtd
->
codec
;
unsigned
short
reg
;
/* Enable voice interface */
reg
=
codec
->
driver
->
read
(
codec
,
TWL4030_REG_VOICE_IF
);
reg
|=
TWL4030_VIF_DIN_EN
|
TWL4030_VIF_DOUT_EN
|
TWL4030_VIF_EN
;
codec
->
driver
->
write
(
codec
,
TWL4030_REG_VOICE_IF
,
reg
);
return
0
;
}
/* Digital audio interface glue - connects codec <--> CPU */
static
struct
snd_soc_dai_link
zoom2_dai
[]
=
{
{
.
name
=
"TWL4030 I2S"
,
.
stream_name
=
"TWL4030 Audio"
,
.
cpu_dai_name
=
"omap-mcbsp.2"
,
.
codec_dai_name
=
"twl4030-hifi"
,
.
platform_name
=
"omap-pcm-audio"
,
.
codec_name
=
"twl4030-codec"
,
.
dai_fmt
=
SND_SOC_DAIFMT_I2S
|
SND_SOC_DAIFMT_NB_NF
|
SND_SOC_DAIFMT_CBM_CFM
,
.
init
=
zoom2_twl4030_init
,
.
ops
=
&
zoom2_ops
,
},
{
.
name
=
"TWL4030 PCM"
,
.
stream_name
=
"TWL4030 Voice"
,
.
cpu_dai_name
=
"omap-mcbsp.3"
,
.
codec_dai_name
=
"twl4030-voice"
,
.
platform_name
=
"omap-pcm-audio"
,
.
codec_name
=
"twl4030-codec"
,
.
dai_fmt
=
SND_SOC_DAIFMT_DSP_A
|
SND_SOC_DAIFMT_IB_NF
|
SND_SOC_DAIFMT_CBM_CFM
,
.
init
=
zoom2_twl4030_voice_init
,
.
ops
=
&
zoom2_ops
,
},
};
/* Audio machine driver */
static
struct
snd_soc_card
snd_soc_zoom2
=
{
.
name
=
"Zoom2"
,
.
owner
=
THIS_MODULE
,
.
dai_link
=
zoom2_dai
,
.
num_links
=
ARRAY_SIZE
(
zoom2_dai
),
.
dapm_widgets
=
zoom2_twl4030_dapm_widgets
,
.
num_dapm_widgets
=
ARRAY_SIZE
(
zoom2_twl4030_dapm_widgets
),
.
dapm_routes
=
audio_map
,
.
num_dapm_routes
=
ARRAY_SIZE
(
audio_map
),
};
static
struct
platform_device
*
zoom2_snd_device
;
static
int
__init
zoom2_soc_init
(
void
)
{
int
ret
;
if
(
!
machine_is_omap_zoom2
())
return
-
ENODEV
;
printk
(
KERN_INFO
"Zoom2 SoC init
\n
"
);
zoom2_snd_device
=
platform_device_alloc
(
"soc-audio"
,
-
1
);
if
(
!
zoom2_snd_device
)
{
printk
(
KERN_ERR
"Platform device allocation failed
\n
"
);
return
-
ENOMEM
;
}
platform_set_drvdata
(
zoom2_snd_device
,
&
snd_soc_zoom2
);
ret
=
platform_device_add
(
zoom2_snd_device
);
if
(
ret
)
goto
err1
;
return
0
;
err1:
printk
(
KERN_ERR
"Unable to add platform device
\n
"
);
platform_device_put
(
zoom2_snd_device
);
return
ret
;
}
module_init
(
zoom2_soc_init
);
static
void
__exit
zoom2_soc_exit
(
void
)
{
platform_device_unregister
(
zoom2_snd_device
);
}
module_exit
(
zoom2_soc_exit
);
MODULE_AUTHOR
(
"Misael Lopez Cruz <x0052729@ti.com>"
);
MODULE_DESCRIPTION
(
"ALSA SoC Zoom2"
);
MODULE_LICENSE
(
"GPL"
);
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录