Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
cloud-kernel
提交
318b0b8d
cloud-kernel
项目概览
openanolis
/
cloud-kernel
1 年多 前同步成功
通知
162
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看板
提交
318b0b8d
编写于
15年前
作者:
M
Mark Brown
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
ASoC: Update WM8711 to driver model registration method
Signed-off-by:
N
Mark Brown
<
broonie@opensource.wolfsonmicro.com
>
上级
bd6d4177
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
129 addition
and
168 deletion
+129
-168
sound/soc/codecs/wm8711.c
sound/soc/codecs/wm8711.c
+129
-168
未找到文件。
sound/soc/codecs/wm8711.c
浏览文件 @
318b0b8d
...
...
@@ -28,11 +28,12 @@
#include "wm8711.h"
#define AUDIO_NAME "wm8711"
#define WM8711_VERSION "0.3"
static
struct
snd_soc_codec
*
wm8711_codec
;
/* codec private data */
struct
wm8711_priv
{
struct
snd_soc_codec
codec
;
u16
reg_cache
[
WM8711_CACHEREGNUM
];
unsigned
int
sysclk
;
};
...
...
@@ -442,241 +443,201 @@ static int wm8711_resume(struct platform_device *pdev)
return
0
;
}
/*
* initialise the WM8711 driver
* register the mixer and dsp interfaces with the kernel
*/
static
int
wm8711_init
(
struct
snd_soc_device
*
socdev
)
static
int
wm8711_probe
(
struct
platform_device
*
pdev
)
{
struct
snd_soc_codec
*
codec
=
socdev
->
card
->
codec
;
int
reg
,
ret
=
0
;
codec
->
name
=
"WM8711"
;
codec
->
owner
=
THIS_MODULE
;
codec
->
read
=
wm8711_read_reg_cache
;
codec
->
write
=
wm8711_write
;
codec
->
set_bias_level
=
wm8711_set_bias_level
;
codec
->
dai
=
&
wm8711_dai
;
codec
->
num_dai
=
1
;
codec
->
reg_cache_size
=
ARRAY_SIZE
(
wm8711_reg
);
codec
->
reg_cache
=
kmemdup
(
wm8711_reg
,
sizeof
(
wm8711_reg
),
GFP_KERNEL
);
struct
snd_soc_device
*
socdev
=
platform_get_drvdata
(
pdev
);
struct
snd_soc_codec
*
codec
;
int
ret
=
0
;
if
(
codec
->
reg_cache
==
NULL
)
return
-
ENOMEM
;
if
(
wm8711_codec
==
NULL
)
{
dev_err
(
&
pdev
->
dev
,
"Codec device not registered
\n
"
);
return
-
ENODEV
;
}
wm8711_reset
(
codec
);
socdev
->
card
->
codec
=
wm8711_codec
;
codec
=
wm8711_codec
;
/* register pcms */
ret
=
snd_soc_new_pcms
(
socdev
,
SNDRV_DEFAULT_IDX1
,
SNDRV_DEFAULT_STR1
);
if
(
ret
<
0
)
{
printk
(
KERN_ERR
"wm8711: failed to create pcms
\n
"
);
dev_err
(
codec
->
dev
,
"failed to create pcms: %d
\n
"
,
ret
);
goto
pcm_err
;
}
/* power on device */
wm8711_set_bias_level
(
codec
,
SND_SOC_BIAS_STANDBY
);
/* set the update bits */
reg
=
wm8711_read_reg_cache
(
codec
,
WM8711_LOUT1V
);
wm8711_write
(
codec
,
WM8711_LOUT1V
,
reg
|
0x0100
);
reg
=
wm8711_read_reg_cache
(
codec
,
WM8711_ROUT1V
);
wm8711_write
(
codec
,
WM8711_ROUT1V
,
reg
|
0x0100
);
wm8711_add_controls
(
codec
);
snd_soc_add_controls
(
codec
,
wm8711_snd_controls
,
ARRAY_SIZE
(
wm8711_snd_controls
));
wm8711_add_widgets
(
codec
);
ret
=
snd_soc_init_card
(
socdev
);
if
(
ret
<
0
)
{
printk
(
KERN_ERR
"wm8711: failed to register card
\n
"
);
dev_err
(
codec
->
dev
,
"failed to register card: %d
\n
"
,
ret
);
goto
card_err
;
}
return
ret
;
card_err:
snd_soc_free_pcms
(
socdev
);
snd_soc_dapm_free
(
socdev
);
pcm_err:
kfree
(
codec
->
reg_cache
);
return
ret
;
}
static
struct
snd_soc_device
*
wm8711_socdev
;
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
/*
* WM8711 2 wire address is determined by GPIO5
* state during powerup.
* low = 0x1a
* high = 0x1b
*/
#define I2C_DRIVERID_WM8711 0xfefe
/* liam - need a proper id */
static
unsigned
short
normal_i2c
[]
=
{
0
,
I2C_CLIENT_END
};
/* power down chip */
static
int
wm8711_remove
(
struct
platform_device
*
pdev
)
{
struct
snd_soc_device
*
socdev
=
platform_get_drvdata
(
pdev
);
/* Magic definition of all other variables and things */
I2C_CLIENT_INSMOD
;
snd_soc_free_pcms
(
socdev
);
snd_soc_dapm_free
(
socdev
)
;
static
struct
i2c_driver
wm8711_i2c_driver
;
static
struct
i2c_client
client_template
;
return
0
;
}
/* If the i2c layer weren't so broken, we could pass this kind of data
around */
struct
snd_soc_codec_device
soc_codec_dev_wm8711
=
{
.
probe
=
wm8711_probe
,
.
remove
=
wm8711_remove
,
.
suspend
=
wm8711_suspend
,
.
resume
=
wm8711_resume
,
};
EXPORT_SYMBOL_GPL
(
soc_codec_dev_wm8711
);
static
int
wm8711_
codec_probe
(
struct
i2c_adapter
*
adap
,
int
addr
,
int
kind
)
static
int
wm8711_
register
(
struct
wm8711_priv
*
wm8711
)
{
struct
snd_soc_device
*
socdev
=
wm8711_socdev
;
struct
wm8711_setup_data
*
setup
=
socdev
->
codec_data
;
struct
snd_soc_codec
*
codec
=
socdev
->
card
->
codec
;
struct
i2c_client
*
i2c
;
int
ret
;
struct
snd_soc_codec
*
codec
=
&
wm8711
->
codec
;
u16
reg
;
if
(
addr
!=
setup
->
i2c_address
)
return
-
ENODEV
;
client_template
.
adapter
=
adap
;
client_template
.
addr
=
addr
;
i2c
=
kmemdup
(
&
client_template
,
sizeof
(
client_template
),
GFP_KERNEL
);
if
(
i2c
==
NULL
)
{
kfree
(
codec
);
return
-
ENOMEM
;
if
(
wm8711_codec
)
{
dev_err
(
codec
->
dev
,
"Another WM8711 is registered
\n
"
);
return
-
EINVAL
;
}
i2c_set_clientdata
(
i2c
,
codec
);
mutex_init
(
&
codec
->
mutex
);
INIT_LIST_HEAD
(
&
codec
->
dapm_widgets
);
INIT_LIST_HEAD
(
&
codec
->
dapm_paths
);
codec
->
control_data
=
i2c
;
codec
->
private_data
=
wm8711
;
codec
->
name
=
"WM8711"
;
codec
->
owner
=
THIS_MODULE
;
codec
->
read
=
wm8711_read_reg_cache
;
codec
->
write
=
wm8711_write
;
codec
->
bias_level
=
SND_SOC_BIAS_OFF
;
codec
->
set_bias_level
=
wm8711_set_bias_level
;
codec
->
dai
=
&
wm8711_dai
;
codec
->
num_dai
=
1
;
codec
->
reg_cache_size
=
WM8711_CACHEREGNUM
;
codec
->
reg_cache
=
&
wm8711
->
reg_cache
;
ret
=
i2c_attach_client
(
i2c
);
if
(
ret
<
0
)
{
pr_err
(
"failed to attach codec at addr %x
\n
"
,
addr
);
goto
err
;
}
memcpy
(
codec
->
reg_cache
,
wm8711_reg
,
sizeof
(
wm8711_reg
));
ret
=
wm8711_
init
(
socdev
);
ret
=
wm8711_
reset
(
codec
);
if
(
ret
<
0
)
{
pr_err
(
"failed to initialise WM8711
\n
"
);
goto
err
;
dev_err
(
codec
->
dev
,
"Failed to issue reset
\n
"
);
return
ret
;
}
return
ret
;
err:
kfree
(
codec
);
kfree
(
i2c
);
return
ret
;
}
wm8711_dai
.
dev
=
codec
->
dev
;
static
int
wm8711_i2c_detach
(
struct
i2c_client
*
client
)
{
struct
snd_soc_codec
*
codec
=
i2c_get_clientdata
(
client
);
wm8711_set_bias_level
(
codec
,
SND_SOC_BIAS_STANDBY
);
/* Latch the update bits */
reg
=
wm8711_read_reg_cache
(
codec
,
WM8711_LOUT1V
);
wm8711_write
(
codec
,
WM8711_LOUT1V
,
reg
|
0x0100
);
reg
=
wm8711_read_reg_cache
(
codec
,
WM8711_ROUT1V
);
wm8711_write
(
codec
,
WM8711_ROUT1V
,
reg
|
0x0100
);
wm8711_codec
=
codec
;
ret
=
snd_soc_register_codec
(
codec
);
if
(
ret
!=
0
)
{
dev_err
(
codec
->
dev
,
"Failed to register codec: %d
\n
"
,
ret
);
return
ret
;
}
ret
=
snd_soc_register_dai
(
&
wm8711_dai
);
if
(
ret
!=
0
)
{
dev_err
(
codec
->
dev
,
"Failed to register DAI: %d
\n
"
,
ret
);
snd_soc_unregister_codec
(
codec
);
return
ret
;
}
i2c_detach_client
(
client
);
kfree
(
codec
->
reg_cache
);
kfree
(
client
);
return
0
;
}
static
int
wm8711_i2c_attach
(
struct
i2c_adapter
*
adap
)
static
void
wm8711_unregister
(
struct
wm8711_priv
*
wm8711
)
{
return
i2c_probe
(
adap
,
&
addr_data
,
wm8711_codec_probe
);
wm8711_set_bias_level
(
&
wm8711
->
codec
,
SND_SOC_BIAS_OFF
);
snd_soc_unregister_dai
(
&
wm8711_dai
);
snd_soc_unregister_codec
(
&
wm8711
->
codec
);
kfree
(
wm8711
);
wm8711_codec
=
NULL
;
}
/* corgi i2c codec control layer */
static
struct
i2c_driver
wm8711_i2c_driver
=
{
.
driver
=
{
.
name
=
"WM8711 I2C Codec"
,
.
owner
=
THIS_MODULE
,
},
.
id
=
I2C_DRIVERID_WM8711
,
.
attach_adapter
=
wm8711_i2c_attach
,
.
detach_client
=
wm8711_i2c_detach
,
.
command
=
NULL
,
};
static
struct
i2c_client
client_template
=
{
.
name
=
"WM8711"
,
.
driver
=
&
wm8711_i2c_driver
,
};
#endif
static
int
wm8711_probe
(
struct
platform_device
*
pdev
)
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
static
__devinit
int
wm8711_i2c_probe
(
struct
i2c_client
*
i2c
,
const
struct
i2c_device_id
*
id
)
{
struct
snd_soc_device
*
socdev
=
platform_get_drvdata
(
pdev
);
struct
wm8711_setup_data
*
setup
;
struct
snd_soc_codec
*
codec
;
struct
wm8711_priv
*
wm8711
;
int
ret
=
0
;
pr_info
(
"WM8711 Audio Codec %s"
,
WM8711_VERSION
);
setup
=
socdev
->
codec_data
;
codec
=
kzalloc
(
sizeof
(
struct
snd_soc_codec
),
GFP_KERNEL
);
if
(
codec
==
NULL
)
return
-
ENOMEM
;
struct
snd_soc_codec
*
codec
;
wm8711
=
kzalloc
(
sizeof
(
struct
wm8711_priv
),
GFP_KERNEL
);
if
(
wm8711
==
NULL
)
{
kfree
(
codec
);
if
(
wm8711
==
NULL
)
return
-
ENOMEM
;
}
codec
->
private_data
=
wm8711
;
socdev
->
card
->
codec
=
codec
;
mutex_init
(
&
codec
->
mutex
);
INIT_LIST_HEAD
(
&
codec
->
dapm_widgets
);
INIT_LIST_HEAD
(
&
codec
->
dapm_paths
);
wm8711_socdev
=
socdev
;
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
if
(
setup
->
i2c_address
)
{
normal_i2c
[
0
]
=
setup
->
i2c_address
;
codec
->
hw_write
=
(
hw_write_t
)
i2c_master_send
;
ret
=
i2c_add_driver
(
&
wm8711_i2c_driver
);
if
(
ret
!=
0
)
printk
(
KERN_ERR
"can't add i2c driver"
);
}
#else
/* Add other interfaces here */
#endif
return
ret
;
}
codec
=
&
wm8711
->
codec
;
codec
->
hw_write
=
(
hw_write_t
)
i2c_master_send
;
/* power down chip */
static
int
wm8711_remove
(
struct
platform_device
*
pdev
)
{
struct
snd_soc_device
*
socdev
=
platform_get_drvdata
(
pdev
);
struct
snd_soc_codec
*
codec
=
socdev
->
card
->
codec
;
i2c_set_clientdata
(
i2c
,
wm8711
);
codec
->
control_data
=
i2c
;
if
(
codec
->
control_data
)
wm8711_set_bias_level
(
codec
,
SND_SOC_BIAS_OFF
);
codec
->
dev
=
&
i2c
->
dev
;
snd_soc_free_pcms
(
socdev
);
snd_soc_dapm_free
(
socdev
);
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
i2c_del_driver
(
&
wm8711_i2c_driver
);
#endif
kfree
(
codec
->
private_data
);
kfree
(
codec
);
return
wm8711_register
(
wm8711
);
}
static
__devexit
int
wm8711_i2c_remove
(
struct
i2c_client
*
client
)
{
struct
wm8711_priv
*
wm8711
=
i2c_get_clientdata
(
client
);
wm8711_unregister
(
wm8711
);
return
0
;
}
struct
snd_soc_codec_device
soc_codec_dev_wm8711
=
{
.
probe
=
wm8711_probe
,
.
remove
=
wm8711_remove
,
.
suspend
=
wm8711_suspend
,
.
resume
=
wm8711_resume
,
static
const
struct
i2c_device_id
wm8711_i2c_id
[]
=
{
{
"wm8711"
,
0
},
{
}
};
EXPORT_SYMBOL_GPL
(
soc_codec_dev_wm8711
);
MODULE_DEVICE_TABLE
(
i2c
,
wm8711_i2c_id
);
static
struct
i2c_driver
wm8711_i2c_driver
=
{
.
driver
=
{
.
name
=
"WM8711 I2C Codec"
,
.
owner
=
THIS_MODULE
,
},
.
probe
=
wm8711_i2c_probe
,
.
remove
=
__devexit_p
(
wm8711_i2c_remove
),
.
id_table
=
wm8711_i2c_id
,
};
#endif
static
int
__init
wm8711_modinit
(
void
)
{
return
snd_soc_register_dai
(
&
wm8711_dai
);
int
ret
;
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
ret
=
i2c_add_driver
(
&
wm8711_i2c_driver
);
if
(
ret
!=
0
)
{
printk
(
KERN_ERR
"Failed to register WM8711 I2C driver: %d
\n
"
,
ret
);
}
#endif
return
0
;
}
module_init
(
wm8711_modinit
);
static
void
__exit
wm8711_exit
(
void
)
{
snd_soc_unregister_dai
(
&
wm8711_dai
);
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
i2c_del_driver
(
&
wm8711_i2c_driver
);
#endif
}
module_exit
(
wm8711_exit
);
...
...
This diff is collapsed.
Click to expand it.
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录
反馈
建议
客服
返回
顶部