aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs/wm8753.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/codecs/wm8753.c')
-rw-r--r--sound/soc/codecs/wm8753.c181
1 files changed, 123 insertions, 58 deletions
diff --git a/sound/soc/codecs/wm8753.c b/sound/soc/codecs/wm8753.c
index 5761164fe16d..d426eaa22185 100644
--- a/sound/soc/codecs/wm8753.c
+++ b/sound/soc/codecs/wm8753.c
@@ -2,8 +2,7 @@
2 * wm8753.c -- WM8753 ALSA Soc Audio driver 2 * wm8753.c -- WM8753 ALSA Soc Audio driver
3 * 3 *
4 * Copyright 2003 Wolfson Microelectronics PLC. 4 * Copyright 2003 Wolfson Microelectronics PLC.
5 * Author: Liam Girdwood 5 * Author: Liam Girdwood <lrg@slimlogic.co.uk>
6 * liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com
7 * 6 *
8 * This program is free software; you can redistribute it and/or modify it 7 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the 8 * under the terms of the GNU General Public License as published by the
@@ -40,6 +39,7 @@
40#include <linux/pm.h> 39#include <linux/pm.h>
41#include <linux/i2c.h> 40#include <linux/i2c.h>
42#include <linux/platform_device.h> 41#include <linux/platform_device.h>
42#include <linux/spi/spi.h>
43#include <sound/core.h> 43#include <sound/core.h>
44#include <sound/pcm.h> 44#include <sound/pcm.h>
45#include <sound/pcm_params.h> 45#include <sound/pcm_params.h>
@@ -51,7 +51,6 @@
51 51
52#include "wm8753.h" 52#include "wm8753.h"
53 53
54#define AUDIO_NAME "wm8753"
55#define WM8753_VERSION "0.16" 54#define WM8753_VERSION "0.16"
56 55
57static int caps_charge = 2000; 56static int caps_charge = 2000;
@@ -583,7 +582,7 @@ static const struct snd_soc_dapm_route audio_map[] = {
583 582
584 /* out 4 */ 583 /* out 4 */
585 {"Out4 Mux", "VREF", "VREF"}, 584 {"Out4 Mux", "VREF", "VREF"},
586 {"Out4 Mux", "Capture ST", "Capture ST Mixer"}, 585 {"Out4 Mux", "Capture ST", "Playback Mixer"},
587 {"Out4 Mux", "LOUT2", "LOUT2"}, 586 {"Out4 Mux", "LOUT2", "LOUT2"},
588 {"Out 4", NULL, "Out4 Mux"}, 587 {"Out 4", NULL, "Out4 Mux"},
589 {"OUT4", NULL, "Out 4"}, 588 {"OUT4", NULL, "Out 4"},
@@ -607,7 +606,7 @@ static const struct snd_soc_dapm_route audio_map[] = {
607 /* Capture Right Mux */ 606 /* Capture Right Mux */
608 {"Capture Right Mux", "PGA", "Right Capture Volume"}, 607 {"Capture Right Mux", "PGA", "Right Capture Volume"},
609 {"Capture Right Mux", "Line or RXP-RXN", "Line Right Mux"}, 608 {"Capture Right Mux", "Line or RXP-RXN", "Line Right Mux"},
610 {"Capture Right Mux", "Sidetone", "Capture ST Mixer"}, 609 {"Capture Right Mux", "Sidetone", "Playback Mixer"},
611 610
612 /* Mono Capture mixer-mux */ 611 /* Mono Capture mixer-mux */
613 {"Capture Right Mixer", "Stereo", "Capture Right Mux"}, 612 {"Capture Right Mixer", "Stereo", "Capture Right Mux"},
@@ -1637,86 +1636,145 @@ static struct snd_soc_device *wm8753_socdev;
1637 * low = 0x1a 1636 * low = 0x1a
1638 * high = 0x1b 1637 * high = 0x1b
1639 */ 1638 */
1640static unsigned short normal_i2c[] = { 0, I2C_CLIENT_END };
1641 1639
1642/* Magic definition of all other variables and things */ 1640static int wm8753_i2c_probe(struct i2c_client *i2c,
1643I2C_CLIENT_INSMOD; 1641 const struct i2c_device_id *id)
1644
1645static struct i2c_driver wm8753_i2c_driver;
1646static struct i2c_client client_template;
1647
1648static int wm8753_codec_probe(struct i2c_adapter *adap, int addr, int kind)
1649{ 1642{
1650 struct snd_soc_device *socdev = wm8753_socdev; 1643 struct snd_soc_device *socdev = wm8753_socdev;
1651 struct wm8753_setup_data *setup = socdev->codec_data;
1652 struct snd_soc_codec *codec = socdev->codec; 1644 struct snd_soc_codec *codec = socdev->codec;
1653 struct i2c_client *i2c;
1654 int ret; 1645 int ret;
1655 1646
1656 if (addr != setup->i2c_address)
1657 return -ENODEV;
1658
1659 client_template.adapter = adap;
1660 client_template.addr = addr;
1661
1662 i2c = kmemdup(&client_template, sizeof(client_template), GFP_KERNEL);
1663 if (!i2c)
1664 return -ENOMEM;
1665
1666 i2c_set_clientdata(i2c, codec); 1647 i2c_set_clientdata(i2c, codec);
1667 codec->control_data = i2c; 1648 codec->control_data = i2c;
1668 1649
1669 ret = i2c_attach_client(i2c);
1670 if (ret < 0) {
1671 pr_err("failed to attach codec at addr %x\n", addr);
1672 goto err;
1673 }
1674
1675 ret = wm8753_init(socdev); 1650 ret = wm8753_init(socdev);
1676 if (ret < 0) { 1651 if (ret < 0)
1677 pr_err("failed to initialise WM8753\n"); 1652 pr_err("failed to initialise WM8753\n");
1678 goto err;
1679 }
1680
1681 return ret;
1682 1653
1683err:
1684 kfree(i2c);
1685 return ret; 1654 return ret;
1686} 1655}
1687 1656
1688static int wm8753_i2c_detach(struct i2c_client *client) 1657static int wm8753_i2c_remove(struct i2c_client *client)
1689{ 1658{
1690 struct snd_soc_codec *codec = i2c_get_clientdata(client); 1659 struct snd_soc_codec *codec = i2c_get_clientdata(client);
1691 i2c_detach_client(client);
1692 kfree(codec->reg_cache); 1660 kfree(codec->reg_cache);
1693 kfree(client);
1694 return 0; 1661 return 0;
1695} 1662}
1696 1663
1697static int wm8753_i2c_attach(struct i2c_adapter *adap) 1664static const struct i2c_device_id wm8753_i2c_id[] = {
1698{ 1665 { "wm8753", 0 },
1699 return i2c_probe(adap, &addr_data, wm8753_codec_probe); 1666 { }
1700} 1667};
1668MODULE_DEVICE_TABLE(i2c, wm8753_i2c_id);
1701 1669
1702/* corgi i2c codec control layer */
1703static struct i2c_driver wm8753_i2c_driver = { 1670static struct i2c_driver wm8753_i2c_driver = {
1704 .driver = { 1671 .driver = {
1705 .name = "WM8753 I2C Codec", 1672 .name = "WM8753 I2C Codec",
1706 .owner = THIS_MODULE, 1673 .owner = THIS_MODULE,
1707 }, 1674 },
1708 .id = I2C_DRIVERID_WM8753, 1675 .probe = wm8753_i2c_probe,
1709 .attach_adapter = wm8753_i2c_attach, 1676 .remove = wm8753_i2c_remove,
1710 .detach_client = wm8753_i2c_detach, 1677 .id_table = wm8753_i2c_id,
1711 .command = NULL,
1712}; 1678};
1713 1679
1714static struct i2c_client client_template = { 1680static int wm8753_add_i2c_device(struct platform_device *pdev,
1715 .name = "WM8753", 1681 const struct wm8753_setup_data *setup)
1716 .driver = &wm8753_i2c_driver, 1682{
1683 struct i2c_board_info info;
1684 struct i2c_adapter *adapter;
1685 struct i2c_client *client;
1686 int ret;
1687
1688 ret = i2c_add_driver(&wm8753_i2c_driver);
1689 if (ret != 0) {
1690 dev_err(&pdev->dev, "can't add i2c driver\n");
1691 return ret;
1692 }
1693
1694 memset(&info, 0, sizeof(struct i2c_board_info));
1695 info.addr = setup->i2c_address;
1696 strlcpy(info.type, "wm8753", I2C_NAME_SIZE);
1697
1698 adapter = i2c_get_adapter(setup->i2c_bus);
1699 if (!adapter) {
1700 dev_err(&pdev->dev, "can't get i2c adapter %d\n",
1701 setup->i2c_bus);
1702 goto err_driver;
1703 }
1704
1705 client = i2c_new_device(adapter, &info);
1706 i2c_put_adapter(adapter);
1707 if (!client) {
1708 dev_err(&pdev->dev, "can't add i2c device at 0x%x\n",
1709 (unsigned int)info.addr);
1710 goto err_driver;
1711 }
1712
1713 return 0;
1714
1715err_driver:
1716 i2c_del_driver(&wm8753_i2c_driver);
1717 return -ENODEV;
1718}
1719#endif
1720
1721#if defined(CONFIG_SPI_MASTER)
1722static int __devinit wm8753_spi_probe(struct spi_device *spi)
1723{
1724 struct snd_soc_device *socdev = wm8753_socdev;
1725 struct snd_soc_codec *codec = socdev->codec;
1726 int ret;
1727
1728 codec->control_data = spi;
1729
1730 ret = wm8753_init(socdev);
1731 if (ret < 0)
1732 dev_err(&spi->dev, "failed to initialise WM8753\n");
1733
1734 return ret;
1735}
1736
1737static int __devexit wm8753_spi_remove(struct spi_device *spi)
1738{
1739 return 0;
1740}
1741
1742static struct spi_driver wm8753_spi_driver = {
1743 .driver = {
1744 .name = "wm8753",
1745 .bus = &spi_bus_type,
1746 .owner = THIS_MODULE,
1747 },
1748 .probe = wm8753_spi_probe,
1749 .remove = __devexit_p(wm8753_spi_remove),
1717}; 1750};
1751
1752static int wm8753_spi_write(struct spi_device *spi, const char *data, int len)
1753{
1754 struct spi_transfer t;
1755 struct spi_message m;
1756 u8 msg[2];
1757
1758 if (len <= 0)
1759 return 0;
1760
1761 msg[0] = data[0];
1762 msg[1] = data[1];
1763
1764 spi_message_init(&m);
1765 memset(&t, 0, (sizeof t));
1766
1767 t.tx_buf = &msg[0];
1768 t.len = len;
1769
1770 spi_message_add_tail(&t, &m);
1771 spi_sync(spi, &m);
1772
1773 return len;
1774}
1718#endif 1775#endif
1719 1776
1777
1720static int wm8753_probe(struct platform_device *pdev) 1778static int wm8753_probe(struct platform_device *pdev)
1721{ 1779{
1722 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 1780 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
@@ -1748,14 +1806,17 @@ static int wm8753_probe(struct platform_device *pdev)
1748 1806
1749#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 1807#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1750 if (setup->i2c_address) { 1808 if (setup->i2c_address) {
1751 normal_i2c[0] = setup->i2c_address;
1752 codec->hw_write = (hw_write_t)i2c_master_send; 1809 codec->hw_write = (hw_write_t)i2c_master_send;
1753 ret = i2c_add_driver(&wm8753_i2c_driver); 1810 ret = wm8753_add_i2c_device(pdev, setup);
1811 }
1812#endif
1813#if defined(CONFIG_SPI_MASTER)
1814 if (setup->spi) {
1815 codec->hw_write = (hw_write_t)wm8753_spi_write;
1816 ret = spi_register_driver(&wm8753_spi_driver);
1754 if (ret != 0) 1817 if (ret != 0)
1755 printk(KERN_ERR "can't add i2c driver"); 1818 printk(KERN_ERR "can't add spi driver");
1756 } 1819 }
1757#else
1758 /* Add other interfaces here */
1759#endif 1820#endif
1760 1821
1761 if (ret != 0) { 1822 if (ret != 0) {
@@ -1796,8 +1857,12 @@ static int wm8753_remove(struct platform_device *pdev)
1796 snd_soc_free_pcms(socdev); 1857 snd_soc_free_pcms(socdev);
1797 snd_soc_dapm_free(socdev); 1858 snd_soc_dapm_free(socdev);
1798#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 1859#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1860 i2c_unregister_device(codec->control_data);
1799 i2c_del_driver(&wm8753_i2c_driver); 1861 i2c_del_driver(&wm8753_i2c_driver);
1800#endif 1862#endif
1863#if defined(CONFIG_SPI_MASTER)
1864 spi_unregister_driver(&wm8753_spi_driver);
1865#endif
1801 kfree(codec->private_data); 1866 kfree(codec->private_data);
1802 kfree(codec); 1867 kfree(codec);
1803 1868