mirror of
https://github.com/a52xq-dev/kernel.git
synced 2026-10-18 21:58:11 +07:00
Merge remote-tracking branches 'asoc/topic/ac97', 'asoc/topic/ac97-mfd', 'asoc/topic/amd' and 'asoc/topic/arizona-mfd' into asoc-next
This commit is contained in:
commit
242f66c845
43 changed files with 2678 additions and 672 deletions
|
|
@ -65,45 +65,6 @@ Optional properties:
|
|||
a value that is out of range for a 16 bit register then the chip default
|
||||
will be used. If present exactly five values must be specified.
|
||||
|
||||
- wlf,inmode : A list of INn_MODE register values, where n is the number
|
||||
of input signals. Valid values are 0 (Differential), 1 (Single-ended) and
|
||||
2 (Digital Microphone). If absent, INn_MODE registers set to 0 by default.
|
||||
If present, values must be specified less than or equal to the number of
|
||||
input signals. If values less than the number of input signals, elements
|
||||
that have not been specified are set to 0 by default. Entries are:
|
||||
<IN1, IN2, IN3, IN4> (wm5102, wm5110, wm8280, wm8997)
|
||||
<IN1A, IN2A, IN1B, IN2B> (wm8998, wm1814)
|
||||
- wlf,out-mono : A list of boolean values indicating whether each output is
|
||||
mono or stereo. Position within the list indicates the output affected
|
||||
(eg. First entry in the list corresponds to output 1). A non-zero value
|
||||
indicates a mono output. If present, the number of values should be less
|
||||
than or equal to the number of outputs, if less values are supplied the
|
||||
additional outputs will be treated as stereo.
|
||||
|
||||
- wlf,dmic-ref : DMIC reference voltage source for each input, can be
|
||||
selected from either MICVDD or one of the MICBIAS's, defines
|
||||
(ARIZONA_DMIC_xxxx) are provided in <dt-bindings/mfd/arizona.txt>. If
|
||||
present, the number of values should be less than or equal to the
|
||||
number of inputs, unspecified inputs will use the chip default.
|
||||
|
||||
- wlf,max-channels-clocked : The maximum number of channels to be clocked on
|
||||
each AIF, useful for I2S systems with multiple data lines being mastered.
|
||||
Specify one cell for each AIF to be configured, specify zero for AIFs that
|
||||
should be handled normally.
|
||||
If present, number of cells must be less than or equal to the number of
|
||||
AIFs. If less than the number of AIFs, for cells that have not been
|
||||
specified the corresponding AIFs will be treated as default setting.
|
||||
|
||||
- wlf,spk-fmt : PDM speaker data format, must contain 2 cells (OUT5 and OUT6).
|
||||
See the datasheet for values.
|
||||
The second cell is ignored for codecs that do not have OUT6 (wm5102, wm8997,
|
||||
wm8998, wm1814)
|
||||
|
||||
- wlf,spk-mute : PDM speaker mute setting, must contain 2 cells (OUT5 and OUT6).
|
||||
See the datasheet for values.
|
||||
The second cell is ignored for codecs that do not have OUT6 (wm5102, wm8997,
|
||||
wm8998, wm1814)
|
||||
|
||||
- DCVDD-supply, MICVDD-supply : Power supplies, only need to be specified if
|
||||
they are being externally supplied. As covered in
|
||||
Documentation/devicetree/bindings/regulator/regulator.txt
|
||||
|
|
@ -112,6 +73,7 @@ Optional properties:
|
|||
Also see child specific device properties:
|
||||
Regulator - ../regulator/arizona-regulator.txt
|
||||
Extcon - ../extcon/extcon-arizona.txt
|
||||
Sound - ../sound/arizona.txt
|
||||
|
||||
Example:
|
||||
|
||||
|
|
|
|||
53
Documentation/devicetree/bindings/sound/wlf,arizona.txt
Normal file
53
Documentation/devicetree/bindings/sound/wlf,arizona.txt
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
Cirrus Logic Arizona class audio SoCs
|
||||
|
||||
These devices are audio SoCs with extensive digital capabilities and a range
|
||||
of analogue I/O.
|
||||
|
||||
This document lists sound specific bindings, see the primary binding
|
||||
document:
|
||||
../mfd/arizona.txt
|
||||
|
||||
Optional properties:
|
||||
|
||||
- wlf,inmode : A list of INn_MODE register values, where n is the number
|
||||
of input signals. Valid values are 0 (Differential), 1 (Single-ended) and
|
||||
2 (Digital Microphone). If absent, INn_MODE registers set to 0 by default.
|
||||
If present, values must be specified less than or equal to the number of
|
||||
input signals. If values less than the number of input signals, elements
|
||||
that have not been specified are set to 0 by default. Entries are:
|
||||
<IN1, IN2, IN3, IN4> (wm5102, wm5110, wm8280, wm8997)
|
||||
<IN1A, IN2A, IN1B, IN2B> (wm8998, wm1814)
|
||||
- wlf,out-mono : A list of boolean values indicating whether each output is
|
||||
mono or stereo. Position within the list indicates the output affected
|
||||
(eg. First entry in the list corresponds to output 1). A non-zero value
|
||||
indicates a mono output. If present, the number of values should be less
|
||||
than or equal to the number of outputs, if less values are supplied the
|
||||
additional outputs will be treated as stereo.
|
||||
|
||||
- wlf,dmic-ref : DMIC reference voltage source for each input, can be
|
||||
selected from either MICVDD or one of the MICBIAS's, defines
|
||||
(ARIZONA_DMIC_xxxx) are provided in <dt-bindings/mfd/arizona.txt>. If
|
||||
present, the number of values should be less than or equal to the
|
||||
number of inputs, unspecified inputs will use the chip default.
|
||||
|
||||
- wlf,max-channels-clocked : The maximum number of channels to be clocked on
|
||||
each AIF, useful for I2S systems with multiple data lines being mastered.
|
||||
Specify one cell for each AIF to be configured, specify zero for AIFs that
|
||||
should be handled normally.
|
||||
If present, number of cells must be less than or equal to the number of
|
||||
AIFs. If less than the number of AIFs, for cells that have not been
|
||||
specified the corresponding AIFs will be treated as default setting.
|
||||
|
||||
- wlf,spk-fmt : PDM speaker data format, must contain 2 cells (OUT5 and OUT6).
|
||||
See the datasheet for values.
|
||||
The second cell is ignored for codecs that do not have OUT6 (wm5102, wm8997,
|
||||
wm8998, wm1814)
|
||||
|
||||
- wlf,spk-mute : PDM speaker mute setting, must contain 2 cells (OUT5 and OUT6).
|
||||
See the datasheet for values.
|
||||
The second cell is ignored for codecs that do not have OUT6 (wm5102, wm8997,
|
||||
wm8998, wm1814)
|
||||
|
||||
- wlf,out-volume-limit : The volume limit value that should be applied to each
|
||||
output channel. See the datasheet for exact values. Channels are specified
|
||||
in the order OUT1L, OUT1R, OUT2L, OUT2R, etc.
|
||||
|
|
@ -14597,6 +14597,7 @@ F: Documentation/devicetree/bindings/extcon/extcon-arizona.txt
|
|||
F: Documentation/devicetree/bindings/regulator/arizona-regulator.txt
|
||||
F: Documentation/devicetree/bindings/mfd/arizona.txt
|
||||
F: Documentation/devicetree/bindings/mfd/wm831x.txt
|
||||
F: Documentation/devicetree/bindings/sound/wlf,arizona.txt
|
||||
F: arch/arm/mach-s3c64xx/mach-crag6410*
|
||||
F: drivers/clk/clk-wm83*.c
|
||||
F: drivers/extcon/extcon-arizona.c
|
||||
|
|
|
|||
|
|
@ -371,6 +371,8 @@ static int acp_hw_init(void *handle)
|
|||
adev->acp.acp_cell[0].name = "acp_audio_dma";
|
||||
adev->acp.acp_cell[0].num_resources = 4;
|
||||
adev->acp.acp_cell[0].resources = &adev->acp.acp_res[0];
|
||||
adev->acp.acp_cell[0].platform_data = &adev->asic_type;
|
||||
adev->acp.acp_cell[0].pdata_size = sizeof(adev->asic_type);
|
||||
|
||||
adev->acp.acp_cell[1].name = "designware-i2s";
|
||||
adev->acp.acp_cell[1].num_resources = 1;
|
||||
|
|
|
|||
|
|
@ -23,34 +23,9 @@
|
|||
#ifndef __AMD_SHARED_H__
|
||||
#define __AMD_SHARED_H__
|
||||
|
||||
#define AMD_MAX_USEC_TIMEOUT 200000 /* 200 ms */
|
||||
#include <drm/amd_asic_type.h>
|
||||
|
||||
/*
|
||||
* Supported ASIC types
|
||||
*/
|
||||
enum amd_asic_type {
|
||||
CHIP_TAHITI = 0,
|
||||
CHIP_PITCAIRN,
|
||||
CHIP_VERDE,
|
||||
CHIP_OLAND,
|
||||
CHIP_HAINAN,
|
||||
CHIP_BONAIRE,
|
||||
CHIP_KAVERI,
|
||||
CHIP_KABINI,
|
||||
CHIP_HAWAII,
|
||||
CHIP_MULLINS,
|
||||
CHIP_TOPAZ,
|
||||
CHIP_TONGA,
|
||||
CHIP_FIJI,
|
||||
CHIP_CARRIZO,
|
||||
CHIP_STONEY,
|
||||
CHIP_POLARIS10,
|
||||
CHIP_POLARIS11,
|
||||
CHIP_POLARIS12,
|
||||
CHIP_VEGA10,
|
||||
CHIP_RAVEN,
|
||||
CHIP_LAST,
|
||||
};
|
||||
#define AMD_MAX_USEC_TIMEOUT 200000 /* 200 ms */
|
||||
|
||||
/*
|
||||
* Chip flags
|
||||
|
|
|
|||
|
|
@ -727,7 +727,7 @@ config TOUCHSCREEN_WM831X
|
|||
|
||||
config TOUCHSCREEN_WM97XX
|
||||
tristate "Support for WM97xx AC97 touchscreen controllers"
|
||||
depends on AC97_BUS
|
||||
depends on AC97_BUS || AC97_BUS_NEW
|
||||
help
|
||||
Say Y here if you have a Wolfson Microelectronics WM97xx
|
||||
touchscreen connected to your system. Note that this option
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@
|
|||
#include <linux/pm.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/mfd/wm97xx.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/wm97xx.h>
|
||||
#include <linux/uaccess.h>
|
||||
|
|
@ -581,27 +582,85 @@ static void wm97xx_ts_input_close(struct input_dev *idev)
|
|||
wm->codec->acc_enable(wm, 0);
|
||||
}
|
||||
|
||||
static int wm97xx_probe(struct device *dev)
|
||||
static int wm97xx_register_touch(struct wm97xx *wm)
|
||||
{
|
||||
struct wm97xx *wm;
|
||||
struct wm97xx_pdata *pdata = dev_get_platdata(dev);
|
||||
int ret = 0, id = 0;
|
||||
struct wm97xx_pdata *pdata = dev_get_platdata(wm->dev);
|
||||
int ret;
|
||||
|
||||
wm = kzalloc(sizeof(struct wm97xx), GFP_KERNEL);
|
||||
if (!wm)
|
||||
wm->input_dev = devm_input_allocate_device(wm->dev);
|
||||
if (wm->input_dev == NULL)
|
||||
return -ENOMEM;
|
||||
mutex_init(&wm->codec_mutex);
|
||||
|
||||
wm->dev = dev;
|
||||
dev_set_drvdata(dev, wm);
|
||||
wm->ac97 = to_ac97_t(dev);
|
||||
/* set up touch configuration */
|
||||
wm->input_dev->name = "wm97xx touchscreen";
|
||||
wm->input_dev->phys = "wm97xx";
|
||||
wm->input_dev->open = wm97xx_ts_input_open;
|
||||
wm->input_dev->close = wm97xx_ts_input_close;
|
||||
|
||||
__set_bit(EV_ABS, wm->input_dev->evbit);
|
||||
__set_bit(EV_KEY, wm->input_dev->evbit);
|
||||
__set_bit(BTN_TOUCH, wm->input_dev->keybit);
|
||||
|
||||
input_set_abs_params(wm->input_dev, ABS_X, abs_x[0], abs_x[1],
|
||||
abs_x[2], 0);
|
||||
input_set_abs_params(wm->input_dev, ABS_Y, abs_y[0], abs_y[1],
|
||||
abs_y[2], 0);
|
||||
input_set_abs_params(wm->input_dev, ABS_PRESSURE, abs_p[0], abs_p[1],
|
||||
abs_p[2], 0);
|
||||
|
||||
input_set_drvdata(wm->input_dev, wm);
|
||||
wm->input_dev->dev.parent = wm->dev;
|
||||
|
||||
ret = input_register_device(wm->input_dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/*
|
||||
* register our extended touch device (for machine specific
|
||||
* extensions)
|
||||
*/
|
||||
wm->touch_dev = platform_device_alloc("wm97xx-touch", -1);
|
||||
if (!wm->touch_dev) {
|
||||
ret = -ENOMEM;
|
||||
goto touch_err;
|
||||
}
|
||||
platform_set_drvdata(wm->touch_dev, wm);
|
||||
wm->touch_dev->dev.parent = wm->dev;
|
||||
wm->touch_dev->dev.platform_data = pdata;
|
||||
ret = platform_device_add(wm->touch_dev);
|
||||
if (ret < 0)
|
||||
goto touch_reg_err;
|
||||
|
||||
return 0;
|
||||
touch_reg_err:
|
||||
platform_device_put(wm->touch_dev);
|
||||
touch_err:
|
||||
input_unregister_device(wm->input_dev);
|
||||
wm->input_dev = NULL;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void wm97xx_unregister_touch(struct wm97xx *wm)
|
||||
{
|
||||
platform_device_unregister(wm->touch_dev);
|
||||
input_unregister_device(wm->input_dev);
|
||||
wm->input_dev = NULL;
|
||||
}
|
||||
|
||||
static int _wm97xx_probe(struct wm97xx *wm)
|
||||
{
|
||||
int id = 0;
|
||||
|
||||
mutex_init(&wm->codec_mutex);
|
||||
dev_set_drvdata(wm->dev, wm);
|
||||
|
||||
/* check that we have a supported codec */
|
||||
id = wm97xx_reg_read(wm, AC97_VENDOR_ID1);
|
||||
if (id != WM97XX_ID1) {
|
||||
dev_err(dev, "Device with vendor %04x is not a wm97xx\n", id);
|
||||
ret = -ENODEV;
|
||||
goto alloc_err;
|
||||
dev_err(wm->dev,
|
||||
"Device with vendor %04x is not a wm97xx\n", id);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
wm->id = wm97xx_reg_read(wm, AC97_VENDOR_ID2);
|
||||
|
|
@ -629,8 +688,7 @@ static int wm97xx_probe(struct device *dev)
|
|||
default:
|
||||
dev_err(wm->dev, "Support for wm97%02x not compiled in.\n",
|
||||
wm->id & 0xff);
|
||||
ret = -ENODEV;
|
||||
goto alloc_err;
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/* set up physical characteristics */
|
||||
|
|
@ -644,79 +702,58 @@ static int wm97xx_probe(struct device *dev)
|
|||
wm->gpio[4] = wm97xx_reg_read(wm, AC97_GPIO_STATUS);
|
||||
wm->gpio[5] = wm97xx_reg_read(wm, AC97_MISC_AFE);
|
||||
|
||||
wm->input_dev = input_allocate_device();
|
||||
if (wm->input_dev == NULL) {
|
||||
ret = -ENOMEM;
|
||||
goto alloc_err;
|
||||
}
|
||||
return wm97xx_register_touch(wm);
|
||||
}
|
||||
|
||||
/* set up touch configuration */
|
||||
wm->input_dev->name = "wm97xx touchscreen";
|
||||
wm->input_dev->phys = "wm97xx";
|
||||
wm->input_dev->open = wm97xx_ts_input_open;
|
||||
wm->input_dev->close = wm97xx_ts_input_close;
|
||||
static void wm97xx_remove_battery(struct wm97xx *wm)
|
||||
{
|
||||
platform_device_unregister(wm->battery_dev);
|
||||
}
|
||||
|
||||
__set_bit(EV_ABS, wm->input_dev->evbit);
|
||||
__set_bit(EV_KEY, wm->input_dev->evbit);
|
||||
__set_bit(BTN_TOUCH, wm->input_dev->keybit);
|
||||
static int wm97xx_add_battery(struct wm97xx *wm,
|
||||
struct wm97xx_batt_pdata *pdata)
|
||||
{
|
||||
int ret;
|
||||
|
||||
input_set_abs_params(wm->input_dev, ABS_X, abs_x[0], abs_x[1],
|
||||
abs_x[2], 0);
|
||||
input_set_abs_params(wm->input_dev, ABS_Y, abs_y[0], abs_y[1],
|
||||
abs_y[2], 0);
|
||||
input_set_abs_params(wm->input_dev, ABS_PRESSURE, abs_p[0], abs_p[1],
|
||||
abs_p[2], 0);
|
||||
|
||||
input_set_drvdata(wm->input_dev, wm);
|
||||
wm->input_dev->dev.parent = dev;
|
||||
|
||||
ret = input_register_device(wm->input_dev);
|
||||
if (ret < 0)
|
||||
goto dev_alloc_err;
|
||||
|
||||
/* register our battery device */
|
||||
wm->battery_dev = platform_device_alloc("wm97xx-battery", -1);
|
||||
if (!wm->battery_dev) {
|
||||
ret = -ENOMEM;
|
||||
goto batt_err;
|
||||
}
|
||||
platform_set_drvdata(wm->battery_dev, wm);
|
||||
wm->battery_dev->dev.parent = dev;
|
||||
wm->battery_dev->dev.platform_data = pdata ? pdata->batt_pdata : NULL;
|
||||
ret = platform_device_add(wm->battery_dev);
|
||||
if (ret < 0)
|
||||
goto batt_reg_err;
|
||||
if (!wm->battery_dev)
|
||||
return -ENOMEM;
|
||||
|
||||
/* register our extended touch device (for machine specific
|
||||
* extensions) */
|
||||
wm->touch_dev = platform_device_alloc("wm97xx-touch", -1);
|
||||
if (!wm->touch_dev) {
|
||||
ret = -ENOMEM;
|
||||
goto touch_err;
|
||||
}
|
||||
platform_set_drvdata(wm->touch_dev, wm);
|
||||
wm->touch_dev->dev.parent = dev;
|
||||
wm->touch_dev->dev.platform_data = pdata;
|
||||
ret = platform_device_add(wm->touch_dev);
|
||||
platform_set_drvdata(wm->battery_dev, wm);
|
||||
wm->battery_dev->dev.parent = wm->dev;
|
||||
wm->battery_dev->dev.platform_data = pdata;
|
||||
ret = platform_device_add(wm->battery_dev);
|
||||
if (ret)
|
||||
platform_device_put(wm->battery_dev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int wm97xx_probe(struct device *dev)
|
||||
{
|
||||
struct wm97xx *wm;
|
||||
int ret;
|
||||
struct wm97xx_pdata *pdata = dev_get_platdata(dev);
|
||||
|
||||
wm = devm_kzalloc(dev, sizeof(struct wm97xx), GFP_KERNEL);
|
||||
if (!wm)
|
||||
return -ENOMEM;
|
||||
|
||||
wm->dev = dev;
|
||||
wm->ac97 = to_ac97_t(dev);
|
||||
|
||||
ret = _wm97xx_probe(wm);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = wm97xx_add_battery(wm, pdata ? pdata->batt_pdata : NULL);
|
||||
if (ret < 0)
|
||||
goto touch_reg_err;
|
||||
goto batt_err;
|
||||
|
||||
return ret;
|
||||
|
||||
touch_reg_err:
|
||||
platform_device_put(wm->touch_dev);
|
||||
touch_err:
|
||||
platform_device_del(wm->battery_dev);
|
||||
batt_reg_err:
|
||||
platform_device_put(wm->battery_dev);
|
||||
batt_err:
|
||||
input_unregister_device(wm->input_dev);
|
||||
wm->input_dev = NULL;
|
||||
dev_alloc_err:
|
||||
input_free_device(wm->input_dev);
|
||||
alloc_err:
|
||||
kfree(wm);
|
||||
|
||||
batt_err:
|
||||
wm97xx_unregister_touch(wm);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -724,14 +761,45 @@ static int wm97xx_remove(struct device *dev)
|
|||
{
|
||||
struct wm97xx *wm = dev_get_drvdata(dev);
|
||||
|
||||
platform_device_unregister(wm->battery_dev);
|
||||
platform_device_unregister(wm->touch_dev);
|
||||
input_unregister_device(wm->input_dev);
|
||||
kfree(wm);
|
||||
wm97xx_remove_battery(wm);
|
||||
wm97xx_unregister_touch(wm);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int wm97xx_mfd_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct wm97xx *wm;
|
||||
struct wm97xx_platform_data *mfd_pdata = dev_get_platdata(&pdev->dev);
|
||||
int ret;
|
||||
|
||||
wm = devm_kzalloc(&pdev->dev, sizeof(struct wm97xx), GFP_KERNEL);
|
||||
if (!wm)
|
||||
return -ENOMEM;
|
||||
|
||||
wm->dev = &pdev->dev;
|
||||
wm->ac97 = mfd_pdata->ac97;
|
||||
|
||||
ret = _wm97xx_probe(wm);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = wm97xx_add_battery(wm, mfd_pdata->batt_pdata);
|
||||
if (ret < 0)
|
||||
goto batt_err;
|
||||
|
||||
return ret;
|
||||
|
||||
batt_err:
|
||||
wm97xx_unregister_touch(wm);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int wm97xx_mfd_remove(struct platform_device *pdev)
|
||||
{
|
||||
return wm97xx_remove(&pdev->dev);
|
||||
}
|
||||
|
||||
static int __maybe_unused wm97xx_suspend(struct device *dev)
|
||||
{
|
||||
struct wm97xx *wm = dev_get_drvdata(dev);
|
||||
|
|
@ -828,21 +896,41 @@ EXPORT_SYMBOL_GPL(wm97xx_unregister_mach_ops);
|
|||
|
||||
static struct device_driver wm97xx_driver = {
|
||||
.name = "wm97xx-ts",
|
||||
#ifdef CONFIG_AC97_BUS
|
||||
.bus = &ac97_bus_type,
|
||||
#endif
|
||||
.owner = THIS_MODULE,
|
||||
.probe = wm97xx_probe,
|
||||
.remove = wm97xx_remove,
|
||||
.pm = &wm97xx_pm_ops,
|
||||
};
|
||||
|
||||
static struct platform_driver wm97xx_mfd_driver = {
|
||||
.driver = {
|
||||
.name = "wm97xx-ts",
|
||||
.pm = &wm97xx_pm_ops,
|
||||
},
|
||||
.probe = wm97xx_mfd_probe,
|
||||
.remove = wm97xx_mfd_remove,
|
||||
};
|
||||
|
||||
static int __init wm97xx_init(void)
|
||||
{
|
||||
return driver_register(&wm97xx_driver);
|
||||
int ret;
|
||||
|
||||
ret = platform_driver_register(&wm97xx_mfd_driver);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (IS_BUILTIN(CONFIG_AC97_BUS))
|
||||
ret = driver_register(&wm97xx_driver);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void __exit wm97xx_exit(void)
|
||||
{
|
||||
driver_unregister(&wm97xx_driver);
|
||||
platform_driver_unregister(&wm97xx_mfd_driver);
|
||||
}
|
||||
|
||||
module_init(wm97xx_init);
|
||||
|
|
|
|||
|
|
@ -1746,6 +1746,20 @@ config MFD_WM8994
|
|||
core support for the WM8994, in order to use the actual
|
||||
functionaltiy of the device other drivers must be enabled.
|
||||
|
||||
config MFD_WM97xx
|
||||
tristate "Wolfson Microelectronics WM97xx"
|
||||
select MFD_CORE
|
||||
select REGMAP_AC97
|
||||
select AC97_BUS_COMPAT
|
||||
depends on AC97_BUS_NEW
|
||||
help
|
||||
The WM9705, WM9712 and WM9713 is a highly integrated hi-fi CODEC
|
||||
designed for smartphone applications. As well as audio functionality
|
||||
it has on board GPIO and a touchscreen functionality which is
|
||||
supported via the relevant subsystems. This driver provides core
|
||||
support for the WM97xx, in order to use the actual functionaltiy of
|
||||
the device other drivers must be enabled.
|
||||
|
||||
config MFD_STW481X
|
||||
tristate "Support for ST Microelectronics STw481x"
|
||||
depends on I2C && (ARCH_NOMADIK || COMPILE_TEST)
|
||||
|
|
|
|||
|
|
@ -74,6 +74,7 @@ obj-$(CONFIG_MFD_WM8350) += wm8350.o
|
|||
obj-$(CONFIG_MFD_WM8350_I2C) += wm8350-i2c.o
|
||||
wm8994-objs := wm8994-core.o wm8994-irq.o wm8994-regmap.o
|
||||
obj-$(CONFIG_MFD_WM8994) += wm8994.o
|
||||
obj-$(CONFIG_MFD_WM97xx) += wm97xx-core.o
|
||||
|
||||
obj-$(CONFIG_TPS6105X) += tps6105x.o
|
||||
obj-$(CONFIG_TPS65010) += tps65010.o
|
||||
|
|
|
|||
|
|
@ -797,12 +797,7 @@ EXPORT_SYMBOL_GPL(arizona_of_get_type);
|
|||
static int arizona_of_get_core_pdata(struct arizona *arizona)
|
||||
{
|
||||
struct arizona_pdata *pdata = &arizona->pdata;
|
||||
struct property *prop;
|
||||
const __be32 *cur;
|
||||
u32 val;
|
||||
u32 pdm_val[ARIZONA_MAX_PDM_SPK];
|
||||
int ret, i;
|
||||
int count = 0;
|
||||
|
||||
pdata->reset = of_get_named_gpio(arizona->dev->of_node, "wlf,reset", 0);
|
||||
if (pdata->reset == -EPROBE_DEFER) {
|
||||
|
|
@ -836,64 +831,6 @@ static int arizona_of_get_core_pdata(struct arizona *arizona)
|
|||
ret);
|
||||
}
|
||||
|
||||
of_property_for_each_u32(arizona->dev->of_node, "wlf,inmode", prop,
|
||||
cur, val) {
|
||||
if (count == ARRAY_SIZE(pdata->inmode))
|
||||
break;
|
||||
|
||||
pdata->inmode[count] = val;
|
||||
count++;
|
||||
}
|
||||
|
||||
count = 0;
|
||||
of_property_for_each_u32(arizona->dev->of_node, "wlf,dmic-ref", prop,
|
||||
cur, val) {
|
||||
if (count == ARRAY_SIZE(pdata->dmic_ref))
|
||||
break;
|
||||
|
||||
pdata->dmic_ref[count] = val;
|
||||
count++;
|
||||
}
|
||||
|
||||
count = 0;
|
||||
of_property_for_each_u32(arizona->dev->of_node, "wlf,out-mono", prop,
|
||||
cur, val) {
|
||||
if (count == ARRAY_SIZE(pdata->out_mono))
|
||||
break;
|
||||
|
||||
pdata->out_mono[count] = !!val;
|
||||
count++;
|
||||
}
|
||||
|
||||
count = 0;
|
||||
of_property_for_each_u32(arizona->dev->of_node,
|
||||
"wlf,max-channels-clocked",
|
||||
prop, cur, val) {
|
||||
if (count == ARRAY_SIZE(pdata->max_channels_clocked))
|
||||
break;
|
||||
|
||||
pdata->max_channels_clocked[count] = val;
|
||||
count++;
|
||||
}
|
||||
|
||||
ret = of_property_read_u32_array(arizona->dev->of_node,
|
||||
"wlf,spk-fmt",
|
||||
pdm_val,
|
||||
ARRAY_SIZE(pdm_val));
|
||||
|
||||
if (ret >= 0)
|
||||
for (count = 0; count < ARRAY_SIZE(pdata->spk_fmt); ++count)
|
||||
pdata->spk_fmt[count] = pdm_val[count];
|
||||
|
||||
ret = of_property_read_u32_array(arizona->dev->of_node,
|
||||
"wlf,spk-mute",
|
||||
pdm_val,
|
||||
ARRAY_SIZE(pdm_val));
|
||||
|
||||
if (ret >= 0)
|
||||
for (count = 0; count < ARRAY_SIZE(pdata->spk_mute); ++count)
|
||||
pdata->spk_mute[count] = pdm_val[count];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -1026,7 +963,7 @@ int arizona_dev_init(struct arizona *arizona)
|
|||
const char * const mclk_name[] = { "mclk1", "mclk2" };
|
||||
struct device *dev = arizona->dev;
|
||||
const char *type_name = NULL;
|
||||
unsigned int reg, val, mask;
|
||||
unsigned int reg, val;
|
||||
int (*apply_patch)(struct arizona *) = NULL;
|
||||
const struct mfd_cell *subdevs = NULL;
|
||||
int n_subdevs, ret, i;
|
||||
|
|
@ -1429,73 +1366,6 @@ int arizona_dev_init(struct arizona *arizona)
|
|||
ARIZONA_MICB1_RATE, val);
|
||||
}
|
||||
|
||||
for (i = 0; i < ARIZONA_MAX_INPUT; i++) {
|
||||
/* Default for both is 0 so noop with defaults */
|
||||
val = arizona->pdata.dmic_ref[i]
|
||||
<< ARIZONA_IN1_DMIC_SUP_SHIFT;
|
||||
if (arizona->pdata.inmode[i] & ARIZONA_INMODE_DMIC)
|
||||
val |= 1 << ARIZONA_IN1_MODE_SHIFT;
|
||||
|
||||
switch (arizona->type) {
|
||||
case WM8998:
|
||||
case WM1814:
|
||||
regmap_update_bits(arizona->regmap,
|
||||
ARIZONA_ADC_DIGITAL_VOLUME_1L + (i * 8),
|
||||
ARIZONA_IN1L_SRC_SE_MASK,
|
||||
(arizona->pdata.inmode[i] & ARIZONA_INMODE_SE)
|
||||
<< ARIZONA_IN1L_SRC_SE_SHIFT);
|
||||
|
||||
regmap_update_bits(arizona->regmap,
|
||||
ARIZONA_ADC_DIGITAL_VOLUME_1R + (i * 8),
|
||||
ARIZONA_IN1R_SRC_SE_MASK,
|
||||
(arizona->pdata.inmode[i] & ARIZONA_INMODE_SE)
|
||||
<< ARIZONA_IN1R_SRC_SE_SHIFT);
|
||||
|
||||
mask = ARIZONA_IN1_DMIC_SUP_MASK |
|
||||
ARIZONA_IN1_MODE_MASK;
|
||||
break;
|
||||
default:
|
||||
if (arizona->pdata.inmode[i] & ARIZONA_INMODE_SE)
|
||||
val |= 1 << ARIZONA_IN1_SINGLE_ENDED_SHIFT;
|
||||
|
||||
mask = ARIZONA_IN1_DMIC_SUP_MASK |
|
||||
ARIZONA_IN1_MODE_MASK |
|
||||
ARIZONA_IN1_SINGLE_ENDED_MASK;
|
||||
break;
|
||||
}
|
||||
|
||||
regmap_update_bits(arizona->regmap,
|
||||
ARIZONA_IN1L_CONTROL + (i * 8),
|
||||
mask, val);
|
||||
}
|
||||
|
||||
for (i = 0; i < ARIZONA_MAX_OUTPUT; i++) {
|
||||
/* Default is 0 so noop with defaults */
|
||||
if (arizona->pdata.out_mono[i])
|
||||
val = ARIZONA_OUT1_MONO;
|
||||
else
|
||||
val = 0;
|
||||
|
||||
regmap_update_bits(arizona->regmap,
|
||||
ARIZONA_OUTPUT_PATH_CONFIG_1L + (i * 8),
|
||||
ARIZONA_OUT1_MONO, val);
|
||||
}
|
||||
|
||||
for (i = 0; i < ARIZONA_MAX_PDM_SPK; i++) {
|
||||
if (arizona->pdata.spk_mute[i])
|
||||
regmap_update_bits(arizona->regmap,
|
||||
ARIZONA_PDM_SPK1_CTRL_1 + (i * 2),
|
||||
ARIZONA_SPK1_MUTE_ENDIAN_MASK |
|
||||
ARIZONA_SPK1_MUTE_SEQ1_MASK,
|
||||
arizona->pdata.spk_mute[i]);
|
||||
|
||||
if (arizona->pdata.spk_fmt[i])
|
||||
regmap_update_bits(arizona->regmap,
|
||||
ARIZONA_PDM_SPK1_CTRL_2 + (i * 2),
|
||||
ARIZONA_SPK1_FMT_MASK,
|
||||
arizona->pdata.spk_fmt[i]);
|
||||
}
|
||||
|
||||
pm_runtime_set_active(arizona->dev);
|
||||
pm_runtime_enable(arizona->dev);
|
||||
|
||||
|
|
|
|||
366
drivers/mfd/wm97xx-core.c
Normal file
366
drivers/mfd/wm97xx-core.c
Normal file
|
|
@ -0,0 +1,366 @@
|
|||
/*
|
||||
* Wolfson WM97xx -- Core device
|
||||
*
|
||||
* Copyright (C) 2017 Robert Jarzmik
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Features:
|
||||
* - an AC97 audio codec
|
||||
* - a touchscreen driver
|
||||
* - a GPIO block
|
||||
*/
|
||||
|
||||
#include <linux/device.h>
|
||||
#include <linux/mfd/core.h>
|
||||
#include <linux/mfd/wm97xx.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/wm97xx.h>
|
||||
#include <sound/ac97/codec.h>
|
||||
#include <sound/ac97/compat.h>
|
||||
|
||||
#define WM9705_VENDOR_ID 0x574d4c05
|
||||
#define WM9712_VENDOR_ID 0x574d4c12
|
||||
#define WM9713_VENDOR_ID 0x574d4c13
|
||||
#define WM97xx_VENDOR_ID_MASK 0xffffffff
|
||||
|
||||
struct wm97xx_priv {
|
||||
struct regmap *regmap;
|
||||
struct snd_ac97 *ac97;
|
||||
struct device *dev;
|
||||
struct wm97xx_platform_data codec_pdata;
|
||||
};
|
||||
|
||||
static bool wm97xx_readable_reg(struct device *dev, unsigned int reg)
|
||||
{
|
||||
switch (reg) {
|
||||
case AC97_RESET ... AC97_PCM_SURR_DAC_RATE:
|
||||
case AC97_PCM_LR_ADC_RATE:
|
||||
case AC97_CENTER_LFE_MASTER:
|
||||
case AC97_SPDIF ... AC97_LINE1_LEVEL:
|
||||
case AC97_GPIO_CFG ... 0x5c:
|
||||
case AC97_CODEC_CLASS_REV ... AC97_PCI_SID:
|
||||
case 0x74 ... AC97_VENDOR_ID2:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static bool wm97xx_writeable_reg(struct device *dev, unsigned int reg)
|
||||
{
|
||||
switch (reg) {
|
||||
case AC97_VENDOR_ID1:
|
||||
case AC97_VENDOR_ID2:
|
||||
return false;
|
||||
default:
|
||||
return wm97xx_readable_reg(dev, reg);
|
||||
}
|
||||
}
|
||||
|
||||
static const struct reg_default wm9705_reg_defaults[] = {
|
||||
{ 0x02, 0x8000 },
|
||||
{ 0x04, 0x8000 },
|
||||
{ 0x06, 0x8000 },
|
||||
{ 0x0a, 0x8000 },
|
||||
{ 0x0c, 0x8008 },
|
||||
{ 0x0e, 0x8008 },
|
||||
{ 0x10, 0x8808 },
|
||||
{ 0x12, 0x8808 },
|
||||
{ 0x14, 0x8808 },
|
||||
{ 0x16, 0x8808 },
|
||||
{ 0x18, 0x8808 },
|
||||
{ 0x1a, 0x0000 },
|
||||
{ 0x1c, 0x8000 },
|
||||
{ 0x20, 0x0000 },
|
||||
{ 0x22, 0x0000 },
|
||||
{ 0x26, 0x000f },
|
||||
{ 0x28, 0x0605 },
|
||||
{ 0x2a, 0x0000 },
|
||||
{ 0x2c, 0xbb80 },
|
||||
{ 0x32, 0xbb80 },
|
||||
{ 0x34, 0x2000 },
|
||||
{ 0x5a, 0x0000 },
|
||||
{ 0x5c, 0x0000 },
|
||||
{ 0x72, 0x0808 },
|
||||
{ 0x74, 0x0000 },
|
||||
{ 0x76, 0x0006 },
|
||||
{ 0x78, 0x0000 },
|
||||
{ 0x7a, 0x0000 },
|
||||
};
|
||||
|
||||
static const struct regmap_config wm9705_regmap_config = {
|
||||
.reg_bits = 16,
|
||||
.reg_stride = 2,
|
||||
.val_bits = 16,
|
||||
.max_register = 0x7e,
|
||||
.cache_type = REGCACHE_RBTREE,
|
||||
|
||||
.reg_defaults = wm9705_reg_defaults,
|
||||
.num_reg_defaults = ARRAY_SIZE(wm9705_reg_defaults),
|
||||
.volatile_reg = regmap_ac97_default_volatile,
|
||||
.readable_reg = wm97xx_readable_reg,
|
||||
.writeable_reg = wm97xx_writeable_reg,
|
||||
};
|
||||
|
||||
static struct mfd_cell wm9705_cells[] = {
|
||||
{ .name = "wm9705-codec", },
|
||||
{ .name = "wm97xx-ts", },
|
||||
};
|
||||
|
||||
static bool wm9712_volatile_reg(struct device *dev, unsigned int reg)
|
||||
{
|
||||
switch (reg) {
|
||||
case AC97_REC_GAIN:
|
||||
return true;
|
||||
default:
|
||||
return regmap_ac97_default_volatile(dev, reg);
|
||||
}
|
||||
}
|
||||
|
||||
static const struct reg_default wm9712_reg_defaults[] = {
|
||||
{ 0x02, 0x8000 },
|
||||
{ 0x04, 0x8000 },
|
||||
{ 0x06, 0x8000 },
|
||||
{ 0x08, 0x0f0f },
|
||||
{ 0x0a, 0xaaa0 },
|
||||
{ 0x0c, 0xc008 },
|
||||
{ 0x0e, 0x6808 },
|
||||
{ 0x10, 0xe808 },
|
||||
{ 0x12, 0xaaa0 },
|
||||
{ 0x14, 0xad00 },
|
||||
{ 0x16, 0x8000 },
|
||||
{ 0x18, 0xe808 },
|
||||
{ 0x1a, 0x3000 },
|
||||
{ 0x1c, 0x8000 },
|
||||
{ 0x20, 0x0000 },
|
||||
{ 0x22, 0x0000 },
|
||||
{ 0x26, 0x000f },
|
||||
{ 0x28, 0x0605 },
|
||||
{ 0x2a, 0x0410 },
|
||||
{ 0x2c, 0xbb80 },
|
||||
{ 0x2e, 0xbb80 },
|
||||
{ 0x32, 0xbb80 },
|
||||
{ 0x34, 0x2000 },
|
||||
{ 0x4c, 0xf83e },
|
||||
{ 0x4e, 0xffff },
|
||||
{ 0x50, 0x0000 },
|
||||
{ 0x52, 0x0000 },
|
||||
{ 0x56, 0xf83e },
|
||||
{ 0x58, 0x0008 },
|
||||
{ 0x5c, 0x0000 },
|
||||
{ 0x60, 0xb032 },
|
||||
{ 0x62, 0x3e00 },
|
||||
{ 0x64, 0x0000 },
|
||||
{ 0x76, 0x0006 },
|
||||
{ 0x78, 0x0001 },
|
||||
{ 0x7a, 0x0000 },
|
||||
};
|
||||
|
||||
static const struct regmap_config wm9712_regmap_config = {
|
||||
.reg_bits = 16,
|
||||
.reg_stride = 2,
|
||||
.val_bits = 16,
|
||||
.max_register = 0x7e,
|
||||
.cache_type = REGCACHE_RBTREE,
|
||||
|
||||
.reg_defaults = wm9712_reg_defaults,
|
||||
.num_reg_defaults = ARRAY_SIZE(wm9712_reg_defaults),
|
||||
.volatile_reg = wm9712_volatile_reg,
|
||||
.readable_reg = wm97xx_readable_reg,
|
||||
.writeable_reg = wm97xx_writeable_reg,
|
||||
};
|
||||
|
||||
static struct mfd_cell wm9712_cells[] = {
|
||||
{ .name = "wm9712-codec", },
|
||||
{ .name = "wm97xx-ts", },
|
||||
};
|
||||
|
||||
static const struct reg_default wm9713_reg_defaults[] = {
|
||||
{ 0x02, 0x8080 }, /* Speaker Output Volume */
|
||||
{ 0x04, 0x8080 }, /* Headphone Output Volume */
|
||||
{ 0x06, 0x8080 }, /* Out3/OUT4 Volume */
|
||||
{ 0x08, 0xc880 }, /* Mono Volume */
|
||||
{ 0x0a, 0xe808 }, /* LINEIN Volume */
|
||||
{ 0x0c, 0xe808 }, /* DAC PGA Volume */
|
||||
{ 0x0e, 0x0808 }, /* MIC PGA Volume */
|
||||
{ 0x10, 0x00da }, /* MIC Routing Control */
|
||||
{ 0x12, 0x8000 }, /* Record PGA Volume */
|
||||
{ 0x14, 0xd600 }, /* Record Routing */
|
||||
{ 0x16, 0xaaa0 }, /* PCBEEP Volume */
|
||||
{ 0x18, 0xaaa0 }, /* VxDAC Volume */
|
||||
{ 0x1a, 0xaaa0 }, /* AUXDAC Volume */
|
||||
{ 0x1c, 0x0000 }, /* Output PGA Mux */
|
||||
{ 0x1e, 0x0000 }, /* DAC 3D control */
|
||||
{ 0x20, 0x0f0f }, /* DAC Tone Control*/
|
||||
{ 0x22, 0x0040 }, /* MIC Input Select & Bias */
|
||||
{ 0x24, 0x0000 }, /* Output Volume Mapping & Jack */
|
||||
{ 0x26, 0x7f00 }, /* Powerdown Ctrl/Stat*/
|
||||
{ 0x28, 0x0405 }, /* Extended Audio ID */
|
||||
{ 0x2a, 0x0410 }, /* Extended Audio Start/Ctrl */
|
||||
{ 0x2c, 0xbb80 }, /* Audio DACs Sample Rate */
|
||||
{ 0x2e, 0xbb80 }, /* AUXDAC Sample Rate */
|
||||
{ 0x32, 0xbb80 }, /* Audio ADCs Sample Rate */
|
||||
{ 0x36, 0x4523 }, /* PCM codec control */
|
||||
{ 0x3a, 0x2000 }, /* SPDIF control */
|
||||
{ 0x3c, 0xfdff }, /* Powerdown 1 */
|
||||
{ 0x3e, 0xffff }, /* Powerdown 2 */
|
||||
{ 0x40, 0x0000 }, /* General Purpose */
|
||||
{ 0x42, 0x0000 }, /* Fast Power-Up Control */
|
||||
{ 0x44, 0x0080 }, /* MCLK/PLL Control */
|
||||
{ 0x46, 0x0000 }, /* MCLK/PLL Control */
|
||||
|
||||
{ 0x4c, 0xfffe }, /* GPIO Pin Configuration */
|
||||
{ 0x4e, 0xffff }, /* GPIO Pin Polarity / Type */
|
||||
{ 0x50, 0x0000 }, /* GPIO Pin Sticky */
|
||||
{ 0x52, 0x0000 }, /* GPIO Pin Wake-Up */
|
||||
/* GPIO Pin Status */
|
||||
{ 0x56, 0xfffe }, /* GPIO Pin Sharing */
|
||||
{ 0x58, 0x4000 }, /* GPIO PullUp/PullDown */
|
||||
{ 0x5a, 0x0000 }, /* Additional Functions 1 */
|
||||
{ 0x5c, 0x0000 }, /* Additional Functions 2 */
|
||||
{ 0x60, 0xb032 }, /* ALC Control */
|
||||
{ 0x62, 0x3e00 }, /* ALC / Noise Gate Control */
|
||||
{ 0x64, 0x0000 }, /* AUXDAC input control */
|
||||
{ 0x74, 0x0000 }, /* Digitiser Reg 1 */
|
||||
{ 0x76, 0x0006 }, /* Digitiser Reg 2 */
|
||||
{ 0x78, 0x0001 }, /* Digitiser Reg 3 */
|
||||
{ 0x7a, 0x0000 }, /* Digitiser Read Back */
|
||||
};
|
||||
|
||||
static const struct regmap_config wm9713_regmap_config = {
|
||||
.reg_bits = 16,
|
||||
.reg_stride = 2,
|
||||
.val_bits = 16,
|
||||
.max_register = 0x7e,
|
||||
.cache_type = REGCACHE_RBTREE,
|
||||
|
||||
.reg_defaults = wm9713_reg_defaults,
|
||||
.num_reg_defaults = ARRAY_SIZE(wm9713_reg_defaults),
|
||||
.volatile_reg = regmap_ac97_default_volatile,
|
||||
.readable_reg = wm97xx_readable_reg,
|
||||
.writeable_reg = wm97xx_writeable_reg,
|
||||
};
|
||||
|
||||
static struct mfd_cell wm9713_cells[] = {
|
||||
{ .name = "wm9713-codec", },
|
||||
{ .name = "wm97xx-ts", },
|
||||
};
|
||||
|
||||
static int wm97xx_ac97_probe(struct ac97_codec_device *adev)
|
||||
{
|
||||
struct wm97xx_priv *wm97xx;
|
||||
const struct regmap_config *config;
|
||||
struct wm97xx_platform_data *codec_pdata;
|
||||
struct mfd_cell *cells;
|
||||
int ret = -ENODEV, nb_cells, i;
|
||||
struct wm97xx_pdata *pdata = snd_ac97_codec_get_platdata(adev);
|
||||
|
||||
wm97xx = devm_kzalloc(ac97_codec_dev2dev(adev),
|
||||
sizeof(*wm97xx), GFP_KERNEL);
|
||||
if (!wm97xx)
|
||||
return -ENOMEM;
|
||||
|
||||
wm97xx->dev = ac97_codec_dev2dev(adev);
|
||||
wm97xx->ac97 = snd_ac97_compat_alloc(adev);
|
||||
if (IS_ERR(wm97xx->ac97))
|
||||
return PTR_ERR(wm97xx->ac97);
|
||||
|
||||
|
||||
ac97_set_drvdata(adev, wm97xx);
|
||||
dev_info(wm97xx->dev, "wm97xx core found, id=0x%x\n",
|
||||
adev->vendor_id);
|
||||
|
||||
codec_pdata = &wm97xx->codec_pdata;
|
||||
codec_pdata->ac97 = wm97xx->ac97;
|
||||
codec_pdata->batt_pdata = pdata->batt_pdata;
|
||||
|
||||
switch (adev->vendor_id) {
|
||||
case WM9705_VENDOR_ID:
|
||||
config = &wm9705_regmap_config;
|
||||
cells = wm9705_cells;
|
||||
nb_cells = ARRAY_SIZE(wm9705_cells);
|
||||
break;
|
||||
case WM9712_VENDOR_ID:
|
||||
config = &wm9712_regmap_config;
|
||||
cells = wm9712_cells;
|
||||
nb_cells = ARRAY_SIZE(wm9712_cells);
|
||||
break;
|
||||
case WM9713_VENDOR_ID:
|
||||
config = &wm9713_regmap_config;
|
||||
cells = wm9713_cells;
|
||||
nb_cells = ARRAY_SIZE(wm9713_cells);
|
||||
break;
|
||||
default:
|
||||
goto err_free_compat;
|
||||
}
|
||||
|
||||
for (i = 0; i < nb_cells; i++) {
|
||||
cells[i].platform_data = codec_pdata;
|
||||
cells[i].pdata_size = sizeof(*codec_pdata);
|
||||
}
|
||||
|
||||
codec_pdata->regmap = devm_regmap_init_ac97(wm97xx->ac97, config);
|
||||
if (IS_ERR(codec_pdata->regmap)) {
|
||||
ret = PTR_ERR(codec_pdata->regmap);
|
||||
goto err_free_compat;
|
||||
}
|
||||
|
||||
ret = devm_mfd_add_devices(wm97xx->dev, PLATFORM_DEVID_NONE,
|
||||
cells, nb_cells, NULL, 0, NULL);
|
||||
if (ret)
|
||||
goto err_free_compat;
|
||||
|
||||
return ret;
|
||||
|
||||
err_free_compat:
|
||||
snd_ac97_compat_release(wm97xx->ac97);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int wm97xx_ac97_remove(struct ac97_codec_device *adev)
|
||||
{
|
||||
struct wm97xx_priv *wm97xx = ac97_get_drvdata(adev);
|
||||
|
||||
snd_ac97_compat_release(wm97xx->ac97);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct ac97_id wm97xx_ac97_ids[] = {
|
||||
{ .id = WM9705_VENDOR_ID, .mask = WM97xx_VENDOR_ID_MASK },
|
||||
{ .id = WM9712_VENDOR_ID, .mask = WM97xx_VENDOR_ID_MASK },
|
||||
{ .id = WM9713_VENDOR_ID, .mask = WM97xx_VENDOR_ID_MASK },
|
||||
{ }
|
||||
};
|
||||
|
||||
static struct ac97_codec_driver wm97xx_ac97_driver = {
|
||||
.driver = {
|
||||
.name = "wm97xx-core",
|
||||
},
|
||||
.probe = wm97xx_ac97_probe,
|
||||
.remove = wm97xx_ac97_remove,
|
||||
.id_table = wm97xx_ac97_ids,
|
||||
};
|
||||
|
||||
static int __init wm97xx_module_init(void)
|
||||
{
|
||||
return snd_ac97_codec_driver_register(&wm97xx_ac97_driver);
|
||||
}
|
||||
module_init(wm97xx_module_init);
|
||||
|
||||
static void __exit wm97xx_module_exit(void)
|
||||
{
|
||||
snd_ac97_codec_driver_unregister(&wm97xx_ac97_driver);
|
||||
}
|
||||
module_exit(wm97xx_module_exit);
|
||||
|
||||
MODULE_DESCRIPTION("WM9712, WM9713 core driver");
|
||||
MODULE_AUTHOR("Robert Jarzmik <robert.jarzmik@free.fr>");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
52
include/drm/amd_asic_type.h
Normal file
52
include/drm/amd_asic_type.h
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* Copyright 2017 Advanced Micro Devices, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef __AMD_ASIC_TYPE_H__
|
||||
#define __AMD_ASIC_TYPE_H__
|
||||
/*
|
||||
* Supported ASIC types
|
||||
*/
|
||||
enum amd_asic_type {
|
||||
CHIP_TAHITI = 0,
|
||||
CHIP_PITCAIRN,
|
||||
CHIP_VERDE,
|
||||
CHIP_OLAND,
|
||||
CHIP_HAINAN,
|
||||
CHIP_BONAIRE,
|
||||
CHIP_KAVERI,
|
||||
CHIP_KABINI,
|
||||
CHIP_HAWAII,
|
||||
CHIP_MULLINS,
|
||||
CHIP_TOPAZ,
|
||||
CHIP_TONGA,
|
||||
CHIP_FIJI,
|
||||
CHIP_CARRIZO,
|
||||
CHIP_STONEY,
|
||||
CHIP_POLARIS10,
|
||||
CHIP_POLARIS11,
|
||||
CHIP_POLARIS12,
|
||||
CHIP_VEGA10,
|
||||
CHIP_RAVEN,
|
||||
CHIP_LAST,
|
||||
};
|
||||
|
||||
#endif /*__AMD_ASIC_TYPE_H__ */
|
||||
|
|
@ -174,6 +174,9 @@ struct arizona_pdata {
|
|||
/** Mode for outputs */
|
||||
int out_mono[ARIZONA_MAX_OUTPUT];
|
||||
|
||||
/** Limit output volumes */
|
||||
unsigned int out_vol_limit[2 * ARIZONA_MAX_OUTPUT];
|
||||
|
||||
/** PDM speaker mute setting */
|
||||
unsigned int spk_mute[ARIZONA_MAX_PDM_SPK];
|
||||
|
||||
|
|
|
|||
25
include/linux/mfd/wm97xx.h
Normal file
25
include/linux/mfd/wm97xx.h
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* wm97xx client interface
|
||||
*
|
||||
* Copyright (C) 2017 Robert Jarzmik
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*/
|
||||
|
||||
#ifndef __LINUX_MFD_WM97XX_H
|
||||
#define __LINUX_MFD_WM97XX_H
|
||||
|
||||
struct regmap;
|
||||
struct wm97xx_batt_pdata;
|
||||
struct snd_ac97;
|
||||
|
||||
struct wm97xx_platform_data {
|
||||
struct snd_ac97 *ac97;
|
||||
struct regmap *regmap;
|
||||
struct wm97xx_batt_pdata *batt_pdata;
|
||||
};
|
||||
|
||||
#endif
|
||||
118
include/sound/ac97/codec.h
Normal file
118
include/sound/ac97/codec.h
Normal file
|
|
@ -0,0 +1,118 @@
|
|||
/*
|
||||
* Copyright (C) 2016 Robert Jarzmik <robert.jarzmik@free.fr>
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
#ifndef __SOUND_AC97_CODEC2_H
|
||||
#define __SOUND_AC97_CODEC2_H
|
||||
|
||||
#include <linux/device.h>
|
||||
|
||||
#define AC97_ID(vendor_id1, vendor_id2) \
|
||||
((((vendor_id1) & 0xffff) << 16) | ((vendor_id2) & 0xffff))
|
||||
#define AC97_DRIVER_ID(vendor_id1, vendor_id2, mask_id1, mask_id2, _data) \
|
||||
{ .id = (((vendor_id1) & 0xffff) << 16) | ((vendor_id2) & 0xffff), \
|
||||
.mask = (((mask_id1) & 0xffff) << 16) | ((mask_id2) & 0xffff), \
|
||||
.data = (_data) }
|
||||
|
||||
struct ac97_controller;
|
||||
struct clk;
|
||||
|
||||
/**
|
||||
* struct ac97_id - matches a codec device and driver on an ac97 bus
|
||||
* @id: The significant bits if the codec vendor ID1 and ID2
|
||||
* @mask: Bitmask specifying which bits of the id field are significant when
|
||||
* matching. A driver binds to a device when :
|
||||
* ((vendorID1 << 8 | vendorID2) & (mask_id1 << 8 | mask_id2)) == id.
|
||||
* @data: Private data used by the driver.
|
||||
*/
|
||||
struct ac97_id {
|
||||
unsigned int id;
|
||||
unsigned int mask;
|
||||
void *data;
|
||||
};
|
||||
|
||||
/**
|
||||
* ac97_codec_device - a ac97 codec
|
||||
* @dev: the core device
|
||||
* @vendor_id: the vendor_id of the codec, as sensed on the AC-link
|
||||
* @num: the codec number, 0 is primary, 1 is first slave, etc ...
|
||||
* @clk: the clock BIT_CLK provided by the codec
|
||||
* @ac97_ctrl: ac97 digital controller on the same AC-link
|
||||
*
|
||||
* This is the device instantiated for each codec living on a AC-link. There are
|
||||
* normally 0 to 4 codec devices per AC-link, and all of them are controlled by
|
||||
* an AC97 digital controller.
|
||||
*/
|
||||
struct ac97_codec_device {
|
||||
struct device dev;
|
||||
unsigned int vendor_id;
|
||||
unsigned int num;
|
||||
struct clk *clk;
|
||||
struct ac97_controller *ac97_ctrl;
|
||||
};
|
||||
|
||||
/**
|
||||
* ac97_codec_driver - a ac97 codec driver
|
||||
* @driver: the device driver structure
|
||||
* @probe: the function called when a ac97_codec_device is matched
|
||||
* @remove: the function called when the device is unbound/removed
|
||||
* @shutdown: shutdown function (might be NULL)
|
||||
* @id_table: ac97 vendor_id match table, { } member terminated
|
||||
*/
|
||||
struct ac97_codec_driver {
|
||||
struct device_driver driver;
|
||||
int (*probe)(struct ac97_codec_device *);
|
||||
int (*remove)(struct ac97_codec_device *);
|
||||
void (*shutdown)(struct ac97_codec_device *);
|
||||
const struct ac97_id *id_table;
|
||||
};
|
||||
|
||||
static inline struct ac97_codec_device *to_ac97_device(struct device *d)
|
||||
{
|
||||
return container_of(d, struct ac97_codec_device, dev);
|
||||
}
|
||||
|
||||
static inline struct ac97_codec_driver *to_ac97_driver(struct device_driver *d)
|
||||
{
|
||||
return container_of(d, struct ac97_codec_driver, driver);
|
||||
}
|
||||
|
||||
#if IS_ENABLED(CONFIG_AC97_BUS_NEW)
|
||||
int snd_ac97_codec_driver_register(struct ac97_codec_driver *drv);
|
||||
void snd_ac97_codec_driver_unregister(struct ac97_codec_driver *drv);
|
||||
#else
|
||||
static inline int
|
||||
snd_ac97_codec_driver_register(struct ac97_codec_driver *drv)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static inline void
|
||||
snd_ac97_codec_driver_unregister(struct ac97_codec_driver *drv)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static inline struct device *
|
||||
ac97_codec_dev2dev(struct ac97_codec_device *adev)
|
||||
{
|
||||
return &adev->dev;
|
||||
}
|
||||
|
||||
static inline void *ac97_get_drvdata(struct ac97_codec_device *adev)
|
||||
{
|
||||
return dev_get_drvdata(ac97_codec_dev2dev(adev));
|
||||
}
|
||||
|
||||
static inline void ac97_set_drvdata(struct ac97_codec_device *adev,
|
||||
void *data)
|
||||
{
|
||||
dev_set_drvdata(ac97_codec_dev2dev(adev), data);
|
||||
}
|
||||
|
||||
void *snd_ac97_codec_get_platdata(const struct ac97_codec_device *adev);
|
||||
|
||||
#endif
|
||||
20
include/sound/ac97/compat.h
Normal file
20
include/sound/ac97/compat.h
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
* Copyright (C) 2016 Robert Jarzmik <robert.jarzmik@free.fr>
|
||||
*
|
||||
* 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 file is for backward compatibility with snd_ac97 structure and its
|
||||
* multiple usages, such as the snd_ac97_bus and snd_ac97_build_ops.
|
||||
*
|
||||
*/
|
||||
#ifndef AC97_COMPAT_H
|
||||
#define AC97_COMPAT_H
|
||||
|
||||
#include <sound/ac97_codec.h>
|
||||
|
||||
struct snd_ac97 *snd_ac97_compat_alloc(struct ac97_codec_device *adev);
|
||||
void snd_ac97_compat_release(struct snd_ac97 *ac97);
|
||||
|
||||
#endif
|
||||
85
include/sound/ac97/controller.h
Normal file
85
include/sound/ac97/controller.h
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
/*
|
||||
* Copyright (C) 2016 Robert Jarzmik <robert.jarzmik@free.fr>
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
#ifndef AC97_CONTROLLER_H
|
||||
#define AC97_CONTROLLER_H
|
||||
|
||||
#include <linux/device.h>
|
||||
#include <linux/list.h>
|
||||
|
||||
#define AC97_BUS_MAX_CODECS 4
|
||||
#define AC97_SLOTS_AVAILABLE_ALL 0xf
|
||||
|
||||
struct ac97_controller_ops;
|
||||
|
||||
/**
|
||||
* struct ac97_controller - The AC97 controller of the AC-Link
|
||||
* @ops: the AC97 operations.
|
||||
* @controllers: linked list of all existing controllers.
|
||||
* @adap: the shell device ac97-%d, ie. ac97 adapter
|
||||
* @nr: the number of the shell device
|
||||
* @slots_available: the mask of accessible/scanable codecs.
|
||||
* @parent: the device providing the AC97 controller.
|
||||
* @codecs: the 4 possible AC97 codecs (NULL if none found).
|
||||
* @codecs_pdata: platform_data for each codec (NULL if no pdata).
|
||||
*
|
||||
* This structure is internal to AC97 bus, and should not be used by the
|
||||
* controllers themselves, excepting for using @dev.
|
||||
*/
|
||||
struct ac97_controller {
|
||||
const struct ac97_controller_ops *ops;
|
||||
struct list_head controllers;
|
||||
struct device adap;
|
||||
int nr;
|
||||
unsigned short slots_available;
|
||||
struct device *parent;
|
||||
struct ac97_codec_device *codecs[AC97_BUS_MAX_CODECS];
|
||||
void *codecs_pdata[AC97_BUS_MAX_CODECS];
|
||||
};
|
||||
|
||||
/**
|
||||
* struct ac97_controller_ops - The AC97 operations
|
||||
* @reset: Cold reset of the AC97 AC-Link.
|
||||
* @warm_reset: Warm reset of the AC97 AC-Link.
|
||||
* @read: Read of a single AC97 register.
|
||||
* Returns the register value or a negative error code.
|
||||
* @write: Write of a single AC97 register.
|
||||
*
|
||||
* These are the basic operation an AC97 controller must provide for an AC97
|
||||
* access functions. Amongst these, all but the last 2 are mandatory.
|
||||
* The slot number is also known as the AC97 codec number, between 0 and 3.
|
||||
*/
|
||||
struct ac97_controller_ops {
|
||||
void (*reset)(struct ac97_controller *adrv);
|
||||
void (*warm_reset)(struct ac97_controller *adrv);
|
||||
int (*write)(struct ac97_controller *adrv, int slot,
|
||||
unsigned short reg, unsigned short val);
|
||||
int (*read)(struct ac97_controller *adrv, int slot, unsigned short reg);
|
||||
};
|
||||
|
||||
#if IS_ENABLED(CONFIG_AC97_BUS_NEW)
|
||||
struct ac97_controller *snd_ac97_controller_register(
|
||||
const struct ac97_controller_ops *ops, struct device *dev,
|
||||
unsigned short slots_available, void **codecs_pdata);
|
||||
void snd_ac97_controller_unregister(struct ac97_controller *ac97_ctrl);
|
||||
#else
|
||||
static inline struct ac97_controller *
|
||||
snd_ac97_controller_register(const struct ac97_controller_ops *ops,
|
||||
struct device *dev,
|
||||
unsigned short slots_available,
|
||||
void **codecs_pdata)
|
||||
{
|
||||
return ERR_PTR(-ENODEV);
|
||||
}
|
||||
|
||||
static inline void
|
||||
snd_ac97_controller_unregister(struct ac97_controller *ac97_ctrl)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
262
include/sound/ac97/regs.h
Normal file
262
include/sound/ac97/regs.h
Normal file
|
|
@ -0,0 +1,262 @@
|
|||
/*
|
||||
* Copyright (c) by Jaroslav Kysela <perex@perex.cz>
|
||||
* Universal interface for Audio Codec '97
|
||||
*
|
||||
* For more details look to AC '97 component specification revision 2.1
|
||||
* by Intel Corporation (http://developer.intel.com).
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* AC'97 codec registers
|
||||
*/
|
||||
|
||||
#define AC97_RESET 0x00 /* Reset */
|
||||
#define AC97_MASTER 0x02 /* Master Volume */
|
||||
#define AC97_HEADPHONE 0x04 /* Headphone Volume (optional) */
|
||||
#define AC97_MASTER_MONO 0x06 /* Master Volume Mono (optional) */
|
||||
#define AC97_MASTER_TONE 0x08 /* Master Tone (Bass & Treble) (optional) */
|
||||
#define AC97_PC_BEEP 0x0a /* PC Beep Volume (optinal) */
|
||||
#define AC97_PHONE 0x0c /* Phone Volume (optional) */
|
||||
#define AC97_MIC 0x0e /* MIC Volume */
|
||||
#define AC97_LINE 0x10 /* Line In Volume */
|
||||
#define AC97_CD 0x12 /* CD Volume */
|
||||
#define AC97_VIDEO 0x14 /* Video Volume (optional) */
|
||||
#define AC97_AUX 0x16 /* AUX Volume (optional) */
|
||||
#define AC97_PCM 0x18 /* PCM Volume */
|
||||
#define AC97_REC_SEL 0x1a /* Record Select */
|
||||
#define AC97_REC_GAIN 0x1c /* Record Gain */
|
||||
#define AC97_REC_GAIN_MIC 0x1e /* Record Gain MIC (optional) */
|
||||
#define AC97_GENERAL_PURPOSE 0x20 /* General Purpose (optional) */
|
||||
#define AC97_3D_CONTROL 0x22 /* 3D Control (optional) */
|
||||
#define AC97_INT_PAGING 0x24 /* Audio Interrupt & Paging (AC'97 2.3) */
|
||||
#define AC97_POWERDOWN 0x26 /* Powerdown control / status */
|
||||
/* range 0x28-0x3a - AUDIO AC'97 2.0 extensions */
|
||||
#define AC97_EXTENDED_ID 0x28 /* Extended Audio ID */
|
||||
#define AC97_EXTENDED_STATUS 0x2a /* Extended Audio Status and Control */
|
||||
#define AC97_PCM_FRONT_DAC_RATE 0x2c /* PCM Front DAC Rate */
|
||||
#define AC97_PCM_SURR_DAC_RATE 0x2e /* PCM Surround DAC Rate */
|
||||
#define AC97_PCM_LFE_DAC_RATE 0x30 /* PCM LFE DAC Rate */
|
||||
#define AC97_PCM_LR_ADC_RATE 0x32 /* PCM LR ADC Rate */
|
||||
#define AC97_PCM_MIC_ADC_RATE 0x34 /* PCM MIC ADC Rate */
|
||||
#define AC97_CENTER_LFE_MASTER 0x36 /* Center + LFE Master Volume */
|
||||
#define AC97_SURROUND_MASTER 0x38 /* Surround (Rear) Master Volume */
|
||||
#define AC97_SPDIF 0x3a /* S/PDIF control */
|
||||
/* range 0x3c-0x58 - MODEM */
|
||||
#define AC97_EXTENDED_MID 0x3c /* Extended Modem ID */
|
||||
#define AC97_EXTENDED_MSTATUS 0x3e /* Extended Modem Status and Control */
|
||||
#define AC97_LINE1_RATE 0x40 /* Line1 DAC/ADC Rate */
|
||||
#define AC97_LINE2_RATE 0x42 /* Line2 DAC/ADC Rate */
|
||||
#define AC97_HANDSET_RATE 0x44 /* Handset DAC/ADC Rate */
|
||||
#define AC97_LINE1_LEVEL 0x46 /* Line1 DAC/ADC Level */
|
||||
#define AC97_LINE2_LEVEL 0x48 /* Line2 DAC/ADC Level */
|
||||
#define AC97_HANDSET_LEVEL 0x4a /* Handset DAC/ADC Level */
|
||||
#define AC97_GPIO_CFG 0x4c /* GPIO Configuration */
|
||||
#define AC97_GPIO_POLARITY 0x4e /* GPIO Pin Polarity/Type, 0=low, 1=high active */
|
||||
#define AC97_GPIO_STICKY 0x50 /* GPIO Pin Sticky, 0=not, 1=sticky */
|
||||
#define AC97_GPIO_WAKEUP 0x52 /* GPIO Pin Wakeup, 0=no int, 1=yes int */
|
||||
#define AC97_GPIO_STATUS 0x54 /* GPIO Pin Status, slot 12 */
|
||||
#define AC97_MISC_AFE 0x56 /* Miscellaneous Modem AFE Status and Control */
|
||||
/* range 0x5a-0x7b - Vendor Specific */
|
||||
#define AC97_VENDOR_ID1 0x7c /* Vendor ID1 */
|
||||
#define AC97_VENDOR_ID2 0x7e /* Vendor ID2 / revision */
|
||||
/* range 0x60-0x6f (page 1) - extended codec registers */
|
||||
#define AC97_CODEC_CLASS_REV 0x60 /* Codec Class/Revision */
|
||||
#define AC97_PCI_SVID 0x62 /* PCI Subsystem Vendor ID */
|
||||
#define AC97_PCI_SID 0x64 /* PCI Subsystem ID */
|
||||
#define AC97_FUNC_SELECT 0x66 /* Function Select */
|
||||
#define AC97_FUNC_INFO 0x68 /* Function Information */
|
||||
#define AC97_SENSE_INFO 0x6a /* Sense Details */
|
||||
|
||||
/* volume controls */
|
||||
#define AC97_MUTE_MASK_MONO 0x8000
|
||||
#define AC97_MUTE_MASK_STEREO 0x8080
|
||||
|
||||
/* slot allocation */
|
||||
#define AC97_SLOT_TAG 0
|
||||
#define AC97_SLOT_CMD_ADDR 1
|
||||
#define AC97_SLOT_CMD_DATA 2
|
||||
#define AC97_SLOT_PCM_LEFT 3
|
||||
#define AC97_SLOT_PCM_RIGHT 4
|
||||
#define AC97_SLOT_MODEM_LINE1 5
|
||||
#define AC97_SLOT_PCM_CENTER 6
|
||||
#define AC97_SLOT_MIC 6 /* input */
|
||||
#define AC97_SLOT_SPDIF_LEFT1 6
|
||||
#define AC97_SLOT_PCM_SLEFT 7 /* surround left */
|
||||
#define AC97_SLOT_PCM_LEFT_0 7 /* double rate operation */
|
||||
#define AC97_SLOT_SPDIF_LEFT 7
|
||||
#define AC97_SLOT_PCM_SRIGHT 8 /* surround right */
|
||||
#define AC97_SLOT_PCM_RIGHT_0 8 /* double rate operation */
|
||||
#define AC97_SLOT_SPDIF_RIGHT 8
|
||||
#define AC97_SLOT_LFE 9
|
||||
#define AC97_SLOT_SPDIF_RIGHT1 9
|
||||
#define AC97_SLOT_MODEM_LINE2 10
|
||||
#define AC97_SLOT_PCM_LEFT_1 10 /* double rate operation */
|
||||
#define AC97_SLOT_SPDIF_LEFT2 10
|
||||
#define AC97_SLOT_HANDSET 11 /* output */
|
||||
#define AC97_SLOT_PCM_RIGHT_1 11 /* double rate operation */
|
||||
#define AC97_SLOT_SPDIF_RIGHT2 11
|
||||
#define AC97_SLOT_MODEM_GPIO 12 /* modem GPIO */
|
||||
#define AC97_SLOT_PCM_CENTER_1 12 /* double rate operation */
|
||||
|
||||
/* basic capabilities (reset register) */
|
||||
#define AC97_BC_DEDICATED_MIC 0x0001 /* Dedicated Mic PCM In Channel */
|
||||
#define AC97_BC_RESERVED1 0x0002 /* Reserved (was Modem Line Codec support) */
|
||||
#define AC97_BC_BASS_TREBLE 0x0004 /* Bass & Treble Control */
|
||||
#define AC97_BC_SIM_STEREO 0x0008 /* Simulated stereo */
|
||||
#define AC97_BC_HEADPHONE 0x0010 /* Headphone Out Support */
|
||||
#define AC97_BC_LOUDNESS 0x0020 /* Loudness (bass boost) Support */
|
||||
#define AC97_BC_16BIT_DAC 0x0000 /* 16-bit DAC resolution */
|
||||
#define AC97_BC_18BIT_DAC 0x0040 /* 18-bit DAC resolution */
|
||||
#define AC97_BC_20BIT_DAC 0x0080 /* 20-bit DAC resolution */
|
||||
#define AC97_BC_DAC_MASK 0x00c0
|
||||
#define AC97_BC_16BIT_ADC 0x0000 /* 16-bit ADC resolution */
|
||||
#define AC97_BC_18BIT_ADC 0x0100 /* 18-bit ADC resolution */
|
||||
#define AC97_BC_20BIT_ADC 0x0200 /* 20-bit ADC resolution */
|
||||
#define AC97_BC_ADC_MASK 0x0300
|
||||
#define AC97_BC_3D_TECH_ID_MASK 0x7c00 /* Per-vendor ID of 3D enhancement */
|
||||
|
||||
/* general purpose */
|
||||
#define AC97_GP_DRSS_MASK 0x0c00 /* double rate slot select */
|
||||
#define AC97_GP_DRSS_1011 0x0000 /* LR(C) 10+11(+12) */
|
||||
#define AC97_GP_DRSS_78 0x0400 /* LR 7+8 */
|
||||
|
||||
/* powerdown bits */
|
||||
#define AC97_PD_ADC_STATUS 0x0001 /* ADC status (RO) */
|
||||
#define AC97_PD_DAC_STATUS 0x0002 /* DAC status (RO) */
|
||||
#define AC97_PD_MIXER_STATUS 0x0004 /* Analog mixer status (RO) */
|
||||
#define AC97_PD_VREF_STATUS 0x0008 /* Vref status (RO) */
|
||||
#define AC97_PD_PR0 0x0100 /* Power down PCM ADCs and input MUX */
|
||||
#define AC97_PD_PR1 0x0200 /* Power down PCM front DAC */
|
||||
#define AC97_PD_PR2 0x0400 /* Power down Mixer (Vref still on) */
|
||||
#define AC97_PD_PR3 0x0800 /* Power down Mixer (Vref off) */
|
||||
#define AC97_PD_PR4 0x1000 /* Power down AC-Link */
|
||||
#define AC97_PD_PR5 0x2000 /* Disable internal clock usage */
|
||||
#define AC97_PD_PR6 0x4000 /* Headphone amplifier */
|
||||
#define AC97_PD_EAPD 0x8000 /* External Amplifer Power Down (EAPD) */
|
||||
|
||||
/* extended audio ID bit defines */
|
||||
#define AC97_EI_VRA 0x0001 /* Variable bit rate supported */
|
||||
#define AC97_EI_DRA 0x0002 /* Double rate supported */
|
||||
#define AC97_EI_SPDIF 0x0004 /* S/PDIF out supported */
|
||||
#define AC97_EI_VRM 0x0008 /* Variable bit rate supported for MIC */
|
||||
#define AC97_EI_DACS_SLOT_MASK 0x0030 /* DACs slot assignment */
|
||||
#define AC97_EI_DACS_SLOT_SHIFT 4
|
||||
#define AC97_EI_CDAC 0x0040 /* PCM Center DAC available */
|
||||
#define AC97_EI_SDAC 0x0080 /* PCM Surround DACs available */
|
||||
#define AC97_EI_LDAC 0x0100 /* PCM LFE DAC available */
|
||||
#define AC97_EI_AMAP 0x0200 /* indicates optional slot/DAC mapping based on codec ID */
|
||||
#define AC97_EI_REV_MASK 0x0c00 /* AC'97 revision mask */
|
||||
#define AC97_EI_REV_22 0x0400 /* AC'97 revision 2.2 */
|
||||
#define AC97_EI_REV_23 0x0800 /* AC'97 revision 2.3 */
|
||||
#define AC97_EI_REV_SHIFT 10
|
||||
#define AC97_EI_ADDR_MASK 0xc000 /* physical codec ID (address) */
|
||||
#define AC97_EI_ADDR_SHIFT 14
|
||||
|
||||
/* extended audio status and control bit defines */
|
||||
#define AC97_EA_VRA 0x0001 /* Variable bit rate enable bit */
|
||||
#define AC97_EA_DRA 0x0002 /* Double-rate audio enable bit */
|
||||
#define AC97_EA_SPDIF 0x0004 /* S/PDIF out enable bit */
|
||||
#define AC97_EA_VRM 0x0008 /* Variable bit rate for MIC enable bit */
|
||||
#define AC97_EA_SPSA_SLOT_MASK 0x0030 /* Mask for slot assignment bits */
|
||||
#define AC97_EA_SPSA_SLOT_SHIFT 4
|
||||
#define AC97_EA_SPSA_3_4 0x0000 /* Slot assigned to 3 & 4 */
|
||||
#define AC97_EA_SPSA_7_8 0x0010 /* Slot assigned to 7 & 8 */
|
||||
#define AC97_EA_SPSA_6_9 0x0020 /* Slot assigned to 6 & 9 */
|
||||
#define AC97_EA_SPSA_10_11 0x0030 /* Slot assigned to 10 & 11 */
|
||||
#define AC97_EA_CDAC 0x0040 /* PCM Center DAC is ready (Read only) */
|
||||
#define AC97_EA_SDAC 0x0080 /* PCM Surround DACs are ready (Read only) */
|
||||
#define AC97_EA_LDAC 0x0100 /* PCM LFE DAC is ready (Read only) */
|
||||
#define AC97_EA_MDAC 0x0200 /* MIC ADC is ready (Read only) */
|
||||
#define AC97_EA_SPCV 0x0400 /* S/PDIF configuration valid (Read only) */
|
||||
#define AC97_EA_PRI 0x0800 /* Turns the PCM Center DAC off */
|
||||
#define AC97_EA_PRJ 0x1000 /* Turns the PCM Surround DACs off */
|
||||
#define AC97_EA_PRK 0x2000 /* Turns the PCM LFE DAC off */
|
||||
#define AC97_EA_PRL 0x4000 /* Turns the MIC ADC off */
|
||||
|
||||
/* S/PDIF control bit defines */
|
||||
#define AC97_SC_PRO 0x0001 /* Professional status */
|
||||
#define AC97_SC_NAUDIO 0x0002 /* Non audio stream */
|
||||
#define AC97_SC_COPY 0x0004 /* Copyright status */
|
||||
#define AC97_SC_PRE 0x0008 /* Preemphasis status */
|
||||
#define AC97_SC_CC_MASK 0x07f0 /* Category Code mask */
|
||||
#define AC97_SC_CC_SHIFT 4
|
||||
#define AC97_SC_L 0x0800 /* Generation Level status */
|
||||
#define AC97_SC_SPSR_MASK 0x3000 /* S/PDIF Sample Rate bits */
|
||||
#define AC97_SC_SPSR_SHIFT 12
|
||||
#define AC97_SC_SPSR_44K 0x0000 /* Use 44.1kHz Sample rate */
|
||||
#define AC97_SC_SPSR_48K 0x2000 /* Use 48kHz Sample rate */
|
||||
#define AC97_SC_SPSR_32K 0x3000 /* Use 32kHz Sample rate */
|
||||
#define AC97_SC_DRS 0x4000 /* Double Rate S/PDIF */
|
||||
#define AC97_SC_V 0x8000 /* Validity status */
|
||||
|
||||
/* Interrupt and Paging bit defines (AC'97 2.3) */
|
||||
#define AC97_PAGE_MASK 0x000f /* Page Selector */
|
||||
#define AC97_PAGE_VENDOR 0 /* Vendor-specific registers */
|
||||
#define AC97_PAGE_1 1 /* Extended Codec Registers page 1 */
|
||||
#define AC97_INT_ENABLE 0x0800 /* Interrupt Enable */
|
||||
#define AC97_INT_SENSE 0x1000 /* Sense Cycle */
|
||||
#define AC97_INT_CAUSE_SENSE 0x2000 /* Sense Cycle Completed (RO) */
|
||||
#define AC97_INT_CAUSE_GPIO 0x4000 /* GPIO bits changed (RO) */
|
||||
#define AC97_INT_STATUS 0x8000 /* Interrupt Status */
|
||||
|
||||
/* extended modem ID bit defines */
|
||||
#define AC97_MEI_LINE1 0x0001 /* Line1 present */
|
||||
#define AC97_MEI_LINE2 0x0002 /* Line2 present */
|
||||
#define AC97_MEI_HANDSET 0x0004 /* Handset present */
|
||||
#define AC97_MEI_CID1 0x0008 /* caller ID decode for Line1 is supported */
|
||||
#define AC97_MEI_CID2 0x0010 /* caller ID decode for Line2 is supported */
|
||||
#define AC97_MEI_ADDR_MASK 0xc000 /* physical codec ID (address) */
|
||||
#define AC97_MEI_ADDR_SHIFT 14
|
||||
|
||||
/* extended modem status and control bit defines */
|
||||
#define AC97_MEA_GPIO 0x0001 /* GPIO is ready (ro) */
|
||||
#define AC97_MEA_MREF 0x0002 /* Vref is up to nominal level (ro) */
|
||||
#define AC97_MEA_ADC1 0x0004 /* ADC1 operational (ro) */
|
||||
#define AC97_MEA_DAC1 0x0008 /* DAC1 operational (ro) */
|
||||
#define AC97_MEA_ADC2 0x0010 /* ADC2 operational (ro) */
|
||||
#define AC97_MEA_DAC2 0x0020 /* DAC2 operational (ro) */
|
||||
#define AC97_MEA_HADC 0x0040 /* HADC operational (ro) */
|
||||
#define AC97_MEA_HDAC 0x0080 /* HDAC operational (ro) */
|
||||
#define AC97_MEA_PRA 0x0100 /* GPIO power down (high) */
|
||||
#define AC97_MEA_PRB 0x0200 /* reserved */
|
||||
#define AC97_MEA_PRC 0x0400 /* ADC1 power down (high) */
|
||||
#define AC97_MEA_PRD 0x0800 /* DAC1 power down (high) */
|
||||
#define AC97_MEA_PRE 0x1000 /* ADC2 power down (high) */
|
||||
#define AC97_MEA_PRF 0x2000 /* DAC2 power down (high) */
|
||||
#define AC97_MEA_PRG 0x4000 /* HADC power down (high) */
|
||||
#define AC97_MEA_PRH 0x8000 /* HDAC power down (high) */
|
||||
|
||||
/* modem gpio status defines */
|
||||
#define AC97_GPIO_LINE1_OH 0x0001 /* Off Hook Line1 */
|
||||
#define AC97_GPIO_LINE1_RI 0x0002 /* Ring Detect Line1 */
|
||||
#define AC97_GPIO_LINE1_CID 0x0004 /* Caller ID path enable Line1 */
|
||||
#define AC97_GPIO_LINE1_LCS 0x0008 /* Loop Current Sense Line1 */
|
||||
#define AC97_GPIO_LINE1_PULSE 0x0010 /* Opt./ Pulse Dial Line1 (out) */
|
||||
#define AC97_GPIO_LINE1_HL1R 0x0020 /* Opt./ Handset to Line1 relay control (out) */
|
||||
#define AC97_GPIO_LINE1_HOHD 0x0040 /* Opt./ Handset off hook detect Line1 (in) */
|
||||
#define AC97_GPIO_LINE12_AC 0x0080 /* Opt./ Int.bit 1 / Line1/2 AC (out) */
|
||||
#define AC97_GPIO_LINE12_DC 0x0100 /* Opt./ Int.bit 2 / Line1/2 DC (out) */
|
||||
#define AC97_GPIO_LINE12_RS 0x0200 /* Opt./ Int.bit 3 / Line1/2 RS (out) */
|
||||
#define AC97_GPIO_LINE2_OH 0x0400 /* Off Hook Line2 */
|
||||
#define AC97_GPIO_LINE2_RI 0x0800 /* Ring Detect Line2 */
|
||||
#define AC97_GPIO_LINE2_CID 0x1000 /* Caller ID path enable Line2 */
|
||||
#define AC97_GPIO_LINE2_LCS 0x2000 /* Loop Current Sense Line2 */
|
||||
#define AC97_GPIO_LINE2_PULSE 0x4000 /* Opt./ Pulse Dial Line2 (out) */
|
||||
#define AC97_GPIO_LINE2_HL1R 0x8000 /* Opt./ Handset to Line2 relay control (out) */
|
||||
|
||||
|
|
@ -28,6 +28,7 @@
|
|||
#include <linux/bitops.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <sound/ac97/regs.h>
|
||||
#include <sound/pcm.h>
|
||||
#include <sound/control.h>
|
||||
#include <sound/info.h>
|
||||
|
|
@ -35,244 +36,6 @@
|
|||
/* maximum number of devices on the AC97 bus */
|
||||
#define AC97_BUS_MAX_DEVICES 4
|
||||
|
||||
/*
|
||||
* AC'97 codec registers
|
||||
*/
|
||||
|
||||
#define AC97_RESET 0x00 /* Reset */
|
||||
#define AC97_MASTER 0x02 /* Master Volume */
|
||||
#define AC97_HEADPHONE 0x04 /* Headphone Volume (optional) */
|
||||
#define AC97_MASTER_MONO 0x06 /* Master Volume Mono (optional) */
|
||||
#define AC97_MASTER_TONE 0x08 /* Master Tone (Bass & Treble) (optional) */
|
||||
#define AC97_PC_BEEP 0x0a /* PC Beep Volume (optinal) */
|
||||
#define AC97_PHONE 0x0c /* Phone Volume (optional) */
|
||||
#define AC97_MIC 0x0e /* MIC Volume */
|
||||
#define AC97_LINE 0x10 /* Line In Volume */
|
||||
#define AC97_CD 0x12 /* CD Volume */
|
||||
#define AC97_VIDEO 0x14 /* Video Volume (optional) */
|
||||
#define AC97_AUX 0x16 /* AUX Volume (optional) */
|
||||
#define AC97_PCM 0x18 /* PCM Volume */
|
||||
#define AC97_REC_SEL 0x1a /* Record Select */
|
||||
#define AC97_REC_GAIN 0x1c /* Record Gain */
|
||||
#define AC97_REC_GAIN_MIC 0x1e /* Record Gain MIC (optional) */
|
||||
#define AC97_GENERAL_PURPOSE 0x20 /* General Purpose (optional) */
|
||||
#define AC97_3D_CONTROL 0x22 /* 3D Control (optional) */
|
||||
#define AC97_INT_PAGING 0x24 /* Audio Interrupt & Paging (AC'97 2.3) */
|
||||
#define AC97_POWERDOWN 0x26 /* Powerdown control / status */
|
||||
/* range 0x28-0x3a - AUDIO AC'97 2.0 extensions */
|
||||
#define AC97_EXTENDED_ID 0x28 /* Extended Audio ID */
|
||||
#define AC97_EXTENDED_STATUS 0x2a /* Extended Audio Status and Control */
|
||||
#define AC97_PCM_FRONT_DAC_RATE 0x2c /* PCM Front DAC Rate */
|
||||
#define AC97_PCM_SURR_DAC_RATE 0x2e /* PCM Surround DAC Rate */
|
||||
#define AC97_PCM_LFE_DAC_RATE 0x30 /* PCM LFE DAC Rate */
|
||||
#define AC97_PCM_LR_ADC_RATE 0x32 /* PCM LR ADC Rate */
|
||||
#define AC97_PCM_MIC_ADC_RATE 0x34 /* PCM MIC ADC Rate */
|
||||
#define AC97_CENTER_LFE_MASTER 0x36 /* Center + LFE Master Volume */
|
||||
#define AC97_SURROUND_MASTER 0x38 /* Surround (Rear) Master Volume */
|
||||
#define AC97_SPDIF 0x3a /* S/PDIF control */
|
||||
/* range 0x3c-0x58 - MODEM */
|
||||
#define AC97_EXTENDED_MID 0x3c /* Extended Modem ID */
|
||||
#define AC97_EXTENDED_MSTATUS 0x3e /* Extended Modem Status and Control */
|
||||
#define AC97_LINE1_RATE 0x40 /* Line1 DAC/ADC Rate */
|
||||
#define AC97_LINE2_RATE 0x42 /* Line2 DAC/ADC Rate */
|
||||
#define AC97_HANDSET_RATE 0x44 /* Handset DAC/ADC Rate */
|
||||
#define AC97_LINE1_LEVEL 0x46 /* Line1 DAC/ADC Level */
|
||||
#define AC97_LINE2_LEVEL 0x48 /* Line2 DAC/ADC Level */
|
||||
#define AC97_HANDSET_LEVEL 0x4a /* Handset DAC/ADC Level */
|
||||
#define AC97_GPIO_CFG 0x4c /* GPIO Configuration */
|
||||
#define AC97_GPIO_POLARITY 0x4e /* GPIO Pin Polarity/Type, 0=low, 1=high active */
|
||||
#define AC97_GPIO_STICKY 0x50 /* GPIO Pin Sticky, 0=not, 1=sticky */
|
||||
#define AC97_GPIO_WAKEUP 0x52 /* GPIO Pin Wakeup, 0=no int, 1=yes int */
|
||||
#define AC97_GPIO_STATUS 0x54 /* GPIO Pin Status, slot 12 */
|
||||
#define AC97_MISC_AFE 0x56 /* Miscellaneous Modem AFE Status and Control */
|
||||
/* range 0x5a-0x7b - Vendor Specific */
|
||||
#define AC97_VENDOR_ID1 0x7c /* Vendor ID1 */
|
||||
#define AC97_VENDOR_ID2 0x7e /* Vendor ID2 / revision */
|
||||
/* range 0x60-0x6f (page 1) - extended codec registers */
|
||||
#define AC97_CODEC_CLASS_REV 0x60 /* Codec Class/Revision */
|
||||
#define AC97_PCI_SVID 0x62 /* PCI Subsystem Vendor ID */
|
||||
#define AC97_PCI_SID 0x64 /* PCI Subsystem ID */
|
||||
#define AC97_FUNC_SELECT 0x66 /* Function Select */
|
||||
#define AC97_FUNC_INFO 0x68 /* Function Information */
|
||||
#define AC97_SENSE_INFO 0x6a /* Sense Details */
|
||||
|
||||
/* volume controls */
|
||||
#define AC97_MUTE_MASK_MONO 0x8000
|
||||
#define AC97_MUTE_MASK_STEREO 0x8080
|
||||
|
||||
/* slot allocation */
|
||||
#define AC97_SLOT_TAG 0
|
||||
#define AC97_SLOT_CMD_ADDR 1
|
||||
#define AC97_SLOT_CMD_DATA 2
|
||||
#define AC97_SLOT_PCM_LEFT 3
|
||||
#define AC97_SLOT_PCM_RIGHT 4
|
||||
#define AC97_SLOT_MODEM_LINE1 5
|
||||
#define AC97_SLOT_PCM_CENTER 6
|
||||
#define AC97_SLOT_MIC 6 /* input */
|
||||
#define AC97_SLOT_SPDIF_LEFT1 6
|
||||
#define AC97_SLOT_PCM_SLEFT 7 /* surround left */
|
||||
#define AC97_SLOT_PCM_LEFT_0 7 /* double rate operation */
|
||||
#define AC97_SLOT_SPDIF_LEFT 7
|
||||
#define AC97_SLOT_PCM_SRIGHT 8 /* surround right */
|
||||
#define AC97_SLOT_PCM_RIGHT_0 8 /* double rate operation */
|
||||
#define AC97_SLOT_SPDIF_RIGHT 8
|
||||
#define AC97_SLOT_LFE 9
|
||||
#define AC97_SLOT_SPDIF_RIGHT1 9
|
||||
#define AC97_SLOT_MODEM_LINE2 10
|
||||
#define AC97_SLOT_PCM_LEFT_1 10 /* double rate operation */
|
||||
#define AC97_SLOT_SPDIF_LEFT2 10
|
||||
#define AC97_SLOT_HANDSET 11 /* output */
|
||||
#define AC97_SLOT_PCM_RIGHT_1 11 /* double rate operation */
|
||||
#define AC97_SLOT_SPDIF_RIGHT2 11
|
||||
#define AC97_SLOT_MODEM_GPIO 12 /* modem GPIO */
|
||||
#define AC97_SLOT_PCM_CENTER_1 12 /* double rate operation */
|
||||
|
||||
/* basic capabilities (reset register) */
|
||||
#define AC97_BC_DEDICATED_MIC 0x0001 /* Dedicated Mic PCM In Channel */
|
||||
#define AC97_BC_RESERVED1 0x0002 /* Reserved (was Modem Line Codec support) */
|
||||
#define AC97_BC_BASS_TREBLE 0x0004 /* Bass & Treble Control */
|
||||
#define AC97_BC_SIM_STEREO 0x0008 /* Simulated stereo */
|
||||
#define AC97_BC_HEADPHONE 0x0010 /* Headphone Out Support */
|
||||
#define AC97_BC_LOUDNESS 0x0020 /* Loudness (bass boost) Support */
|
||||
#define AC97_BC_16BIT_DAC 0x0000 /* 16-bit DAC resolution */
|
||||
#define AC97_BC_18BIT_DAC 0x0040 /* 18-bit DAC resolution */
|
||||
#define AC97_BC_20BIT_DAC 0x0080 /* 20-bit DAC resolution */
|
||||
#define AC97_BC_DAC_MASK 0x00c0
|
||||
#define AC97_BC_16BIT_ADC 0x0000 /* 16-bit ADC resolution */
|
||||
#define AC97_BC_18BIT_ADC 0x0100 /* 18-bit ADC resolution */
|
||||
#define AC97_BC_20BIT_ADC 0x0200 /* 20-bit ADC resolution */
|
||||
#define AC97_BC_ADC_MASK 0x0300
|
||||
#define AC97_BC_3D_TECH_ID_MASK 0x7c00 /* Per-vendor ID of 3D enhancement */
|
||||
|
||||
/* general purpose */
|
||||
#define AC97_GP_DRSS_MASK 0x0c00 /* double rate slot select */
|
||||
#define AC97_GP_DRSS_1011 0x0000 /* LR(C) 10+11(+12) */
|
||||
#define AC97_GP_DRSS_78 0x0400 /* LR 7+8 */
|
||||
|
||||
/* powerdown bits */
|
||||
#define AC97_PD_ADC_STATUS 0x0001 /* ADC status (RO) */
|
||||
#define AC97_PD_DAC_STATUS 0x0002 /* DAC status (RO) */
|
||||
#define AC97_PD_MIXER_STATUS 0x0004 /* Analog mixer status (RO) */
|
||||
#define AC97_PD_VREF_STATUS 0x0008 /* Vref status (RO) */
|
||||
#define AC97_PD_PR0 0x0100 /* Power down PCM ADCs and input MUX */
|
||||
#define AC97_PD_PR1 0x0200 /* Power down PCM front DAC */
|
||||
#define AC97_PD_PR2 0x0400 /* Power down Mixer (Vref still on) */
|
||||
#define AC97_PD_PR3 0x0800 /* Power down Mixer (Vref off) */
|
||||
#define AC97_PD_PR4 0x1000 /* Power down AC-Link */
|
||||
#define AC97_PD_PR5 0x2000 /* Disable internal clock usage */
|
||||
#define AC97_PD_PR6 0x4000 /* Headphone amplifier */
|
||||
#define AC97_PD_EAPD 0x8000 /* External Amplifer Power Down (EAPD) */
|
||||
|
||||
/* extended audio ID bit defines */
|
||||
#define AC97_EI_VRA 0x0001 /* Variable bit rate supported */
|
||||
#define AC97_EI_DRA 0x0002 /* Double rate supported */
|
||||
#define AC97_EI_SPDIF 0x0004 /* S/PDIF out supported */
|
||||
#define AC97_EI_VRM 0x0008 /* Variable bit rate supported for MIC */
|
||||
#define AC97_EI_DACS_SLOT_MASK 0x0030 /* DACs slot assignment */
|
||||
#define AC97_EI_DACS_SLOT_SHIFT 4
|
||||
#define AC97_EI_CDAC 0x0040 /* PCM Center DAC available */
|
||||
#define AC97_EI_SDAC 0x0080 /* PCM Surround DACs available */
|
||||
#define AC97_EI_LDAC 0x0100 /* PCM LFE DAC available */
|
||||
#define AC97_EI_AMAP 0x0200 /* indicates optional slot/DAC mapping based on codec ID */
|
||||
#define AC97_EI_REV_MASK 0x0c00 /* AC'97 revision mask */
|
||||
#define AC97_EI_REV_22 0x0400 /* AC'97 revision 2.2 */
|
||||
#define AC97_EI_REV_23 0x0800 /* AC'97 revision 2.3 */
|
||||
#define AC97_EI_REV_SHIFT 10
|
||||
#define AC97_EI_ADDR_MASK 0xc000 /* physical codec ID (address) */
|
||||
#define AC97_EI_ADDR_SHIFT 14
|
||||
|
||||
/* extended audio status and control bit defines */
|
||||
#define AC97_EA_VRA 0x0001 /* Variable bit rate enable bit */
|
||||
#define AC97_EA_DRA 0x0002 /* Double-rate audio enable bit */
|
||||
#define AC97_EA_SPDIF 0x0004 /* S/PDIF out enable bit */
|
||||
#define AC97_EA_VRM 0x0008 /* Variable bit rate for MIC enable bit */
|
||||
#define AC97_EA_SPSA_SLOT_MASK 0x0030 /* Mask for slot assignment bits */
|
||||
#define AC97_EA_SPSA_SLOT_SHIFT 4
|
||||
#define AC97_EA_SPSA_3_4 0x0000 /* Slot assigned to 3 & 4 */
|
||||
#define AC97_EA_SPSA_7_8 0x0010 /* Slot assigned to 7 & 8 */
|
||||
#define AC97_EA_SPSA_6_9 0x0020 /* Slot assigned to 6 & 9 */
|
||||
#define AC97_EA_SPSA_10_11 0x0030 /* Slot assigned to 10 & 11 */
|
||||
#define AC97_EA_CDAC 0x0040 /* PCM Center DAC is ready (Read only) */
|
||||
#define AC97_EA_SDAC 0x0080 /* PCM Surround DACs are ready (Read only) */
|
||||
#define AC97_EA_LDAC 0x0100 /* PCM LFE DAC is ready (Read only) */
|
||||
#define AC97_EA_MDAC 0x0200 /* MIC ADC is ready (Read only) */
|
||||
#define AC97_EA_SPCV 0x0400 /* S/PDIF configuration valid (Read only) */
|
||||
#define AC97_EA_PRI 0x0800 /* Turns the PCM Center DAC off */
|
||||
#define AC97_EA_PRJ 0x1000 /* Turns the PCM Surround DACs off */
|
||||
#define AC97_EA_PRK 0x2000 /* Turns the PCM LFE DAC off */
|
||||
#define AC97_EA_PRL 0x4000 /* Turns the MIC ADC off */
|
||||
|
||||
/* S/PDIF control bit defines */
|
||||
#define AC97_SC_PRO 0x0001 /* Professional status */
|
||||
#define AC97_SC_NAUDIO 0x0002 /* Non audio stream */
|
||||
#define AC97_SC_COPY 0x0004 /* Copyright status */
|
||||
#define AC97_SC_PRE 0x0008 /* Preemphasis status */
|
||||
#define AC97_SC_CC_MASK 0x07f0 /* Category Code mask */
|
||||
#define AC97_SC_CC_SHIFT 4
|
||||
#define AC97_SC_L 0x0800 /* Generation Level status */
|
||||
#define AC97_SC_SPSR_MASK 0x3000 /* S/PDIF Sample Rate bits */
|
||||
#define AC97_SC_SPSR_SHIFT 12
|
||||
#define AC97_SC_SPSR_44K 0x0000 /* Use 44.1kHz Sample rate */
|
||||
#define AC97_SC_SPSR_48K 0x2000 /* Use 48kHz Sample rate */
|
||||
#define AC97_SC_SPSR_32K 0x3000 /* Use 32kHz Sample rate */
|
||||
#define AC97_SC_DRS 0x4000 /* Double Rate S/PDIF */
|
||||
#define AC97_SC_V 0x8000 /* Validity status */
|
||||
|
||||
/* Interrupt and Paging bit defines (AC'97 2.3) */
|
||||
#define AC97_PAGE_MASK 0x000f /* Page Selector */
|
||||
#define AC97_PAGE_VENDOR 0 /* Vendor-specific registers */
|
||||
#define AC97_PAGE_1 1 /* Extended Codec Registers page 1 */
|
||||
#define AC97_INT_ENABLE 0x0800 /* Interrupt Enable */
|
||||
#define AC97_INT_SENSE 0x1000 /* Sense Cycle */
|
||||
#define AC97_INT_CAUSE_SENSE 0x2000 /* Sense Cycle Completed (RO) */
|
||||
#define AC97_INT_CAUSE_GPIO 0x4000 /* GPIO bits changed (RO) */
|
||||
#define AC97_INT_STATUS 0x8000 /* Interrupt Status */
|
||||
|
||||
/* extended modem ID bit defines */
|
||||
#define AC97_MEI_LINE1 0x0001 /* Line1 present */
|
||||
#define AC97_MEI_LINE2 0x0002 /* Line2 present */
|
||||
#define AC97_MEI_HANDSET 0x0004 /* Handset present */
|
||||
#define AC97_MEI_CID1 0x0008 /* caller ID decode for Line1 is supported */
|
||||
#define AC97_MEI_CID2 0x0010 /* caller ID decode for Line2 is supported */
|
||||
#define AC97_MEI_ADDR_MASK 0xc000 /* physical codec ID (address) */
|
||||
#define AC97_MEI_ADDR_SHIFT 14
|
||||
|
||||
/* extended modem status and control bit defines */
|
||||
#define AC97_MEA_GPIO 0x0001 /* GPIO is ready (ro) */
|
||||
#define AC97_MEA_MREF 0x0002 /* Vref is up to nominal level (ro) */
|
||||
#define AC97_MEA_ADC1 0x0004 /* ADC1 operational (ro) */
|
||||
#define AC97_MEA_DAC1 0x0008 /* DAC1 operational (ro) */
|
||||
#define AC97_MEA_ADC2 0x0010 /* ADC2 operational (ro) */
|
||||
#define AC97_MEA_DAC2 0x0020 /* DAC2 operational (ro) */
|
||||
#define AC97_MEA_HADC 0x0040 /* HADC operational (ro) */
|
||||
#define AC97_MEA_HDAC 0x0080 /* HDAC operational (ro) */
|
||||
#define AC97_MEA_PRA 0x0100 /* GPIO power down (high) */
|
||||
#define AC97_MEA_PRB 0x0200 /* reserved */
|
||||
#define AC97_MEA_PRC 0x0400 /* ADC1 power down (high) */
|
||||
#define AC97_MEA_PRD 0x0800 /* DAC1 power down (high) */
|
||||
#define AC97_MEA_PRE 0x1000 /* ADC2 power down (high) */
|
||||
#define AC97_MEA_PRF 0x2000 /* DAC2 power down (high) */
|
||||
#define AC97_MEA_PRG 0x4000 /* HADC power down (high) */
|
||||
#define AC97_MEA_PRH 0x8000 /* HDAC power down (high) */
|
||||
|
||||
/* modem gpio status defines */
|
||||
#define AC97_GPIO_LINE1_OH 0x0001 /* Off Hook Line1 */
|
||||
#define AC97_GPIO_LINE1_RI 0x0002 /* Ring Detect Line1 */
|
||||
#define AC97_GPIO_LINE1_CID 0x0004 /* Caller ID path enable Line1 */
|
||||
#define AC97_GPIO_LINE1_LCS 0x0008 /* Loop Current Sense Line1 */
|
||||
#define AC97_GPIO_LINE1_PULSE 0x0010 /* Opt./ Pulse Dial Line1 (out) */
|
||||
#define AC97_GPIO_LINE1_HL1R 0x0020 /* Opt./ Handset to Line1 relay control (out) */
|
||||
#define AC97_GPIO_LINE1_HOHD 0x0040 /* Opt./ Handset off hook detect Line1 (in) */
|
||||
#define AC97_GPIO_LINE12_AC 0x0080 /* Opt./ Int.bit 1 / Line1/2 AC (out) */
|
||||
#define AC97_GPIO_LINE12_DC 0x0100 /* Opt./ Int.bit 2 / Line1/2 DC (out) */
|
||||
#define AC97_GPIO_LINE12_RS 0x0200 /* Opt./ Int.bit 3 / Line1/2 RS (out) */
|
||||
#define AC97_GPIO_LINE2_OH 0x0400 /* Off Hook Line2 */
|
||||
#define AC97_GPIO_LINE2_RI 0x0800 /* Ring Detect Line2 */
|
||||
#define AC97_GPIO_LINE2_CID 0x1000 /* Caller ID path enable Line2 */
|
||||
#define AC97_GPIO_LINE2_LCS 0x2000 /* Loop Current Sense Line2 */
|
||||
#define AC97_GPIO_LINE2_PULSE 0x4000 /* Opt./ Pulse Dial Line2 (out) */
|
||||
#define AC97_GPIO_LINE2_HL1R 0x8000 /* Opt./ Handset to Line2 relay control (out) */
|
||||
|
||||
/* specific - SigmaTel */
|
||||
#define AC97_SIGMATEL_OUTSEL 0x64 /* Output Select, STAC9758 */
|
||||
#define AC97_SIGMATEL_INSEL 0x66 /* Input Select, STAC9758 */
|
||||
|
|
|
|||
|
|
@ -2,10 +2,13 @@
|
|||
#ifndef PXA2XX_LIB_H
|
||||
#define PXA2XX_LIB_H
|
||||
|
||||
#include <uapi/sound/asound.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <sound/ac97_codec.h>
|
||||
|
||||
/* PCM */
|
||||
struct snd_pcm_substream;
|
||||
struct snd_pcm_hw_params;
|
||||
struct snd_pcm;
|
||||
|
||||
extern int __pxa2xx_pcm_hw_params(struct snd_pcm_substream *substream,
|
||||
struct snd_pcm_hw_params *params);
|
||||
|
|
@ -22,12 +25,12 @@ extern void pxa2xx_pcm_free_dma_buffers(struct snd_pcm *pcm);
|
|||
|
||||
/* AC97 */
|
||||
|
||||
extern unsigned short pxa2xx_ac97_read(struct snd_ac97 *ac97, unsigned short reg);
|
||||
extern void pxa2xx_ac97_write(struct snd_ac97 *ac97, unsigned short reg, unsigned short val);
|
||||
extern int pxa2xx_ac97_read(int slot, unsigned short reg);
|
||||
extern int pxa2xx_ac97_write(int slot, unsigned short reg, unsigned short val);
|
||||
|
||||
extern bool pxa2xx_ac97_try_warm_reset(struct snd_ac97 *ac97);
|
||||
extern bool pxa2xx_ac97_try_cold_reset(struct snd_ac97 *ac97);
|
||||
extern void pxa2xx_ac97_finish_reset(struct snd_ac97 *ac97);
|
||||
extern bool pxa2xx_ac97_try_warm_reset(void);
|
||||
extern bool pxa2xx_ac97_try_cold_reset(void);
|
||||
extern void pxa2xx_ac97_finish_reset(void);
|
||||
|
||||
extern int pxa2xx_ac97_hw_suspend(void);
|
||||
extern int pxa2xx_ac97_hw_resume(void);
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue