提交 aa0e25ca 编写于 作者: A Ashish Chavan 提交者: Mark Brown

ASoC: da7210: Add support for spi regmap

This patch adds support for spi regmap feature to existing da7210
driver.
Signed-off-by: NAshish Chavan <ashish.chavan@kpitcummins.com>
Signed-off-by: NDavid Dajun Chen <dchen@diasemi.com>
Signed-off-by: NMark Brown <broonie@opensource.wolfsonmicro.com>
上级 eb794077
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/spi/spi.h>
#include <linux/regmap.h> #include <linux/regmap.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/module.h> #include <linux/module.h>
...@@ -27,6 +28,7 @@ ...@@ -27,6 +28,7 @@
#include <sound/tlv.h> #include <sound/tlv.h>
/* DA7210 register space */ /* DA7210 register space */
#define DA7210_PAGE_CONTROL 0x00
#define DA7210_CONTROL 0x01 #define DA7210_CONTROL 0x01
#define DA7210_STATUS 0x02 #define DA7210_STATUS 0x02
#define DA7210_STARTUP1 0x03 #define DA7210_STARTUP1 0x03
...@@ -631,6 +633,7 @@ struct da7210_priv { ...@@ -631,6 +633,7 @@ struct da7210_priv {
}; };
static struct reg_default da7210_reg_defaults[] = { static struct reg_default da7210_reg_defaults[] = {
{ 0x00, 0x00 },
{ 0x01, 0x11 }, { 0x01, 0x11 },
{ 0x03, 0x00 }, { 0x03, 0x00 },
{ 0x04, 0x00 }, { 0x04, 0x00 },
...@@ -927,13 +930,6 @@ static int da7210_probe(struct snd_soc_codec *codec) ...@@ -927,13 +930,6 @@ static int da7210_probe(struct snd_soc_codec *codec)
* DA7210_PLL_DIV3 :: DA7210_MCLK_RANGExxx * DA7210_PLL_DIV3 :: DA7210_MCLK_RANGExxx
*/ */
/*
* make sure that DA7210 use bypass mode before start up
*/
snd_soc_write(codec, DA7210_STARTUP1, 0);
snd_soc_write(codec, DA7210_PLL_DIV3,
DA7210_MCLK_RANGE_10_20_MHZ | DA7210_PLL_BYP);
/* /*
* ADC settings * ADC settings
*/ */
...@@ -1025,16 +1021,6 @@ static int da7210_probe(struct snd_soc_codec *codec) ...@@ -1025,16 +1021,6 @@ static int da7210_probe(struct snd_soc_codec *codec)
DA7210_MCLK_RANGE_10_20_MHZ | DA7210_PLL_BYP); DA7210_MCLK_RANGE_10_20_MHZ | DA7210_PLL_BYP);
snd_soc_update_bits(codec, DA7210_PLL, DA7210_PLL_EN, DA7210_PLL_EN); snd_soc_update_bits(codec, DA7210_PLL, DA7210_PLL_EN, DA7210_PLL_EN);
/* As suggested by Dialog */
/* unlock */
regmap_write(da7210->regmap, DA7210_A_HID_UNLOCK, 0x8B);
regmap_write(da7210->regmap, DA7210_A_TEST_UNLOCK, 0xB4);
regmap_write(da7210->regmap, DA7210_A_PLL1, 0x01);
regmap_write(da7210->regmap, DA7210_A_CP_MODE, 0x7C);
/* re-lock */
regmap_write(da7210->regmap, DA7210_A_HID_UNLOCK, 0x00);
regmap_write(da7210->regmap, DA7210_A_TEST_UNLOCK, 0x00);
/* Activate all enabled subsystem */ /* Activate all enabled subsystem */
snd_soc_write(codec, DA7210_STARTUP1, DA7210_SC_MST_EN); snd_soc_write(codec, DA7210_STARTUP1, DA7210_SC_MST_EN);
...@@ -1055,7 +1041,26 @@ static struct snd_soc_codec_driver soc_codec_dev_da7210 = { ...@@ -1055,7 +1041,26 @@ static struct snd_soc_codec_driver soc_codec_dev_da7210 = {
.num_dapm_routes = ARRAY_SIZE(da7210_audio_map), .num_dapm_routes = ARRAY_SIZE(da7210_audio_map),
}; };
static struct regmap_config da7210_regmap = { #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
static struct reg_default da7210_regmap_i2c_patch[] = {
/* System controller master disable */
{ DA7210_STARTUP1, 0x00 },
/* make sure that DA7210 use bypass mode before start up */
{ DA7210_PLL_DIV3, DA7210_MCLK_RANGE_10_20_MHZ | DA7210_PLL_BYP },
/* to unlock */
{ DA7210_A_HID_UNLOCK, 0x8B},
{ DA7210_A_TEST_UNLOCK, 0xB4},
{ DA7210_A_PLL1, 0x01},
{ DA7210_A_CP_MODE, 0x7C},
/* to re-lock */
{ DA7210_A_HID_UNLOCK, 0x00},
{ DA7210_A_TEST_UNLOCK, 0x00},
};
static const struct regmap_config da7210_regmap_config_i2c = {
.reg_bits = 8, .reg_bits = 8,
.val_bits = 8, .val_bits = 8,
...@@ -1066,7 +1071,6 @@ static struct regmap_config da7210_regmap = { ...@@ -1066,7 +1071,6 @@ static struct regmap_config da7210_regmap = {
.cache_type = REGCACHE_RBTREE, .cache_type = REGCACHE_RBTREE,
}; };
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
static int __devinit da7210_i2c_probe(struct i2c_client *i2c, static int __devinit da7210_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id) const struct i2c_device_id *id)
{ {
...@@ -1080,13 +1084,18 @@ static int __devinit da7210_i2c_probe(struct i2c_client *i2c, ...@@ -1080,13 +1084,18 @@ static int __devinit da7210_i2c_probe(struct i2c_client *i2c,
i2c_set_clientdata(i2c, da7210); i2c_set_clientdata(i2c, da7210);
da7210->regmap = regmap_init_i2c(i2c, &da7210_regmap); da7210->regmap = regmap_init_i2c(i2c, &da7210_regmap_config_i2c);
if (IS_ERR(da7210->regmap)) { if (IS_ERR(da7210->regmap)) {
ret = PTR_ERR(da7210->regmap); ret = PTR_ERR(da7210->regmap);
dev_err(&i2c->dev, "regmap_init() failed: %d\n", ret); dev_err(&i2c->dev, "regmap_init() failed: %d\n", ret);
return ret; return ret;
} }
ret = regmap_register_patch(da7210->regmap, da7210_regmap_i2c_patch,
ARRAY_SIZE(da7210_regmap_i2c_patch));
if (ret != 0)
dev_warn(&i2c->dev, "Failed to apply regmap patch: %d\n", ret);
ret = snd_soc_register_codec(&i2c->dev, ret = snd_soc_register_codec(&i2c->dev,
&soc_codec_dev_da7210, &da7210_dai, 1); &soc_codec_dev_da7210, &da7210_dai, 1);
if (ret < 0) { if (ret < 0) {
...@@ -1119,7 +1128,7 @@ MODULE_DEVICE_TABLE(i2c, da7210_i2c_id); ...@@ -1119,7 +1128,7 @@ MODULE_DEVICE_TABLE(i2c, da7210_i2c_id);
/* I2C codec control layer */ /* I2C codec control layer */
static struct i2c_driver da7210_i2c_driver = { static struct i2c_driver da7210_i2c_driver = {
.driver = { .driver = {
.name = "da7210-codec", .name = "da7210",
.owner = THIS_MODULE, .owner = THIS_MODULE,
}, },
.probe = da7210_i2c_probe, .probe = da7210_i2c_probe,
...@@ -1128,11 +1137,111 @@ static struct i2c_driver da7210_i2c_driver = { ...@@ -1128,11 +1137,111 @@ static struct i2c_driver da7210_i2c_driver = {
}; };
#endif #endif
#if defined(CONFIG_SPI_MASTER)
static struct reg_default da7210_regmap_spi_patch[] = {
/* Dummy read to give two pulses over nCS for SPI */
{ DA7210_AUX2, 0x00 },
{ DA7210_AUX2, 0x00 },
/* System controller master disable */
{ DA7210_STARTUP1, 0x00 },
/* make sure that DA7210 use bypass mode before start up */
{ DA7210_PLL_DIV3, DA7210_MCLK_RANGE_10_20_MHZ | DA7210_PLL_BYP },
/* to set PAGE1 of SPI register space */
{ DA7210_PAGE_CONTROL, 0x80 },
/* to unlock */
{ DA7210_A_HID_UNLOCK, 0x8B},
{ DA7210_A_TEST_UNLOCK, 0xB4},
{ DA7210_A_PLL1, 0x01},
{ DA7210_A_CP_MODE, 0x7C},
/* to re-lock */
{ DA7210_A_HID_UNLOCK, 0x00},
{ DA7210_A_TEST_UNLOCK, 0x00},
/* to set back PAGE0 of SPI register space */
{ DA7210_PAGE_CONTROL, 0x00 },
};
static const struct regmap_config da7210_regmap_config_spi = {
.reg_bits = 8,
.val_bits = 8,
.read_flag_mask = 0x01,
.write_flag_mask = 0x00,
.reg_defaults = da7210_reg_defaults,
.num_reg_defaults = ARRAY_SIZE(da7210_reg_defaults),
.volatile_reg = da7210_volatile_register,
.readable_reg = da7210_readable_register,
.cache_type = REGCACHE_RBTREE,
};
static int __devinit da7210_spi_probe(struct spi_device *spi)
{
struct da7210_priv *da7210;
int ret;
da7210 = devm_kzalloc(&spi->dev, sizeof(struct da7210_priv),
GFP_KERNEL);
if (!da7210)
return -ENOMEM;
spi_set_drvdata(spi, da7210);
da7210->regmap = devm_regmap_init_spi(spi, &da7210_regmap_config_spi);
if (IS_ERR(da7210->regmap)) {
ret = PTR_ERR(da7210->regmap);
dev_err(&spi->dev, "Failed to register regmap: %d\n", ret);
return ret;
}
ret = regmap_register_patch(da7210->regmap, da7210_regmap_spi_patch,
ARRAY_SIZE(da7210_regmap_spi_patch));
if (ret != 0)
dev_warn(&spi->dev, "Failed to apply regmap patch: %d\n", ret);
ret = snd_soc_register_codec(&spi->dev,
&soc_codec_dev_da7210, &da7210_dai, 1);
if (ret < 0)
goto err_regmap;
return ret;
err_regmap:
regmap_exit(da7210->regmap);
return ret;
}
static int __devexit da7210_spi_remove(struct spi_device *spi)
{
struct da7210_priv *da7210 = spi_get_drvdata(spi);
snd_soc_unregister_codec(&spi->dev);
regmap_exit(da7210->regmap);
return 0;
}
static struct spi_driver da7210_spi_driver = {
.driver = {
.name = "da7210",
.owner = THIS_MODULE,
},
.probe = da7210_spi_probe,
.remove = __devexit_p(da7210_spi_remove)
};
#endif
static int __init da7210_modinit(void) static int __init da7210_modinit(void)
{ {
int ret = 0; int ret = 0;
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
ret = i2c_add_driver(&da7210_i2c_driver); ret = i2c_add_driver(&da7210_i2c_driver);
#endif
#if defined(CONFIG_SPI_MASTER)
ret = spi_register_driver(&da7210_spi_driver);
if (ret) {
printk(KERN_ERR "Failed to register da7210 SPI driver: %d\n",
ret);
}
#endif #endif
return ret; return ret;
} }
...@@ -1143,6 +1252,9 @@ static void __exit da7210_exit(void) ...@@ -1143,6 +1252,9 @@ static void __exit da7210_exit(void)
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
i2c_del_driver(&da7210_i2c_driver); i2c_del_driver(&da7210_i2c_driver);
#endif #endif
#if defined(CONFIG_SPI_MASTER)
spi_unregister_driver(&da7210_spi_driver);
#endif
} }
module_exit(da7210_exit); module_exit(da7210_exit);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册