|
17 | 17 | #include <linux/acpi.h>
|
18 | 18 | #include <linux/clk.h>
|
19 | 19 | #include <linux/device.h>
|
| 20 | +#include <linux/device/bus.h> |
20 | 21 | #include <linux/dmi.h>
|
21 | 22 | #include <linux/gpio/consumer.h>
|
22 | 23 | #include <linux/gpio/machine.h>
|
|
32 | 33 | #include "../atom/sst-atom-controls.h"
|
33 | 34 | #include "../common/soc-intel-quirks.h"
|
34 | 35 |
|
| 36 | +#define BYT_RT5640_FALLBACK_CODEC_DEV_NAME "i2c-rt5640" |
| 37 | + |
35 | 38 | enum {
|
36 | 39 | BYT_RT5640_DMIC1_MAP,
|
37 | 40 | BYT_RT5640_DMIC2_MAP,
|
@@ -1698,9 +1701,33 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev)
|
1698 | 1701 |
|
1699 | 1702 | codec_dev = acpi_get_first_physical_node(adev);
|
1700 | 1703 | acpi_dev_put(adev);
|
1701 |
| - if (!codec_dev) |
1702 |
| - return -EPROBE_DEFER; |
1703 |
| - priv->codec_dev = get_device(codec_dev); |
| 1704 | + |
| 1705 | + if (codec_dev) { |
| 1706 | + priv->codec_dev = get_device(codec_dev); |
| 1707 | + } else { |
| 1708 | + /* |
| 1709 | + * Special case for Android tablets where the codec i2c_client |
| 1710 | + * has been manually instantiated by x86_android_tablets.ko due |
| 1711 | + * to a broken DSDT. |
| 1712 | + */ |
| 1713 | + codec_dev = bus_find_device_by_name(&i2c_bus_type, NULL, |
| 1714 | + BYT_RT5640_FALLBACK_CODEC_DEV_NAME); |
| 1715 | + if (!codec_dev) |
| 1716 | + return -EPROBE_DEFER; |
| 1717 | + |
| 1718 | + if (!i2c_verify_client(codec_dev)) { |
| 1719 | + dev_err(dev, "Error '%s' is not an i2c_client\n", |
| 1720 | + BYT_RT5640_FALLBACK_CODEC_DEV_NAME); |
| 1721 | + put_device(codec_dev); |
| 1722 | + } |
| 1723 | + |
| 1724 | + /* fixup codec name */ |
| 1725 | + strscpy(byt_rt5640_codec_name, BYT_RT5640_FALLBACK_CODEC_DEV_NAME, |
| 1726 | + sizeof(byt_rt5640_codec_name)); |
| 1727 | + |
| 1728 | + /* bus_find_device() returns a reference no need to get() */ |
| 1729 | + priv->codec_dev = codec_dev; |
| 1730 | + } |
1704 | 1731 |
|
1705 | 1732 | /*
|
1706 | 1733 | * swap SSP0 if bytcr is detected
|
|
0 commit comments