Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

i2s: phytium: Add Phytium i2s driver support #189

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions drivers/mfd/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -1107,6 +1107,20 @@ config PCF50633_GPIO
Say yes here if you want to include support GPIO for pins on
the PCF50633 chip.

config MFD_PHYTIUM_I2S_LSD
bool "PHYTIUM Px210 I2S LSD MFD driver"
depends on (PCI && ARCH_PHYTIUM)
select MFD_CORE
help
This enables support for the Phytium Px210 LSD I2S controller.

config MFD_PHYTIUM_I2S_MMD
bool "PHYTIUM Px210 I2S MMD MFD driver"
depends on (PCI && ARCH_PHYTIUM)
help
This enables support for the Phytium Px210 MMD I2S controllers
for Display Port.

config MFD_PM8XXX
tristate "Qualcomm PM8xxx PMIC chips driver"
depends on (ARM || HEXAGON || COMPILE_TEST)
Expand Down
3 changes: 3 additions & 0 deletions drivers/mfd/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -284,3 +284,6 @@ rsmu-i2c-objs := rsmu_core.o rsmu_i2c.o
rsmu-spi-objs := rsmu_core.o rsmu_spi.o
obj-$(CONFIG_MFD_RSMU_I2C) += rsmu-i2c.o
obj-$(CONFIG_MFD_RSMU_SPI) += rsmu-spi.o

obj-$(CONFIG_MFD_PHYTIUM_I2S_LSD) += phytium_px210_i2s_lsd.o
obj-$(CONFIG_MFD_PHYTIUM_I2S_MMD) += phytium_px210_i2s_mmd.o
131 changes: 131 additions & 0 deletions drivers/mfd/phytium_px210_i2s_lsd.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Phytium I2S LSD MFD driver over PCI bus
*
* Copyright (C) 2020-2023, Phytium Technology Co., Ltd.
*/

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/mfd/core.h>

struct phytium_px210_mfd {
struct device *dev;
};

struct pdata_px210_mfd {
struct device *dev;
char *name;
int clk_base;
};

static struct resource phytium_px210_i2s_res0[] = {
[0] = {
.flags = IORESOURCE_MEM,
},
[1] = {
.flags = IORESOURCE_MEM,
},
[2] = {
.flags = IORESOURCE_IRQ,
},
};

static struct mfd_cell phytium_px210_mfd_cells[] = {
{
.id = 0,
.name = "phytium-i2s",
.of_compatible = "phytium,i2s",
.resources = phytium_px210_i2s_res0,
.num_resources = ARRAY_SIZE(phytium_px210_i2s_res0),
.ignore_resource_conflicts = true,
},
};

static void phytium_px210_i2s_setup(struct pci_dev *pdev)
{
struct mfd_cell *cell = &phytium_px210_mfd_cells[0];
struct resource *res = (struct resource *)cell->resources;
struct pdata_px210_mfd *pdata;

res[0].start = pci_resource_start(pdev, 0);
res[0].end = pci_resource_start(pdev, 0) + 0x0fff;

res[1].start = pci_resource_start(pdev, 0) + 0x1000;
res[1].end = pci_resource_start(pdev, 0) + 0x1fff;

res[2].start = pdev->irq;
res[2].end = pdev->irq;

pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);

pdata->dev = &pdev->dev;
pdata->name = "phytium-i2s-lsd";
pdata->clk_base = 480000000;

cell->platform_data = pdata;
cell->pdata_size = sizeof(*pdata);
}

static int phytium_px210_mfd_probe(struct pci_dev *pdev,
const struct pci_device_id *id)
{
struct phytium_px210_mfd *phytium_mfd;
int ret;

ret = pcim_enable_device(pdev);
if (ret)
return ret;

pci_set_master(pdev);

phytium_mfd = devm_kzalloc(&pdev->dev, sizeof(*phytium_mfd), GFP_KERNEL);
if (!phytium_mfd)
return -ENOMEM;

phytium_mfd->dev = &pdev->dev;
dev_set_drvdata(&pdev->dev, phytium_mfd);

phytium_px210_i2s_setup(pdev);

ret = mfd_add_devices(&pdev->dev, 0, phytium_px210_mfd_cells,
ARRAY_SIZE(phytium_px210_mfd_cells), NULL, 0,
NULL);
if (ret)
return 0;

return 0;
}


static void phytium_px210_mfd_remove(struct pci_dev *pdev)
{
mfd_remove_devices(&pdev->dev);
}

static const struct pci_device_id phytium_px210_mfd_ids[] = {
{
.vendor = 0x1DB7,
.device = 0xDC2B,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
.class = 0x3,
.class_mask = 0,
},
{},
};
MODULE_DEVICE_TABLE(pci, phytium_px210_mfd_ids);

static struct pci_driver phytium_i2s_lsd_mfd_driver = {
.name = "phytium_px210_mfd_i2s",
.id_table = phytium_px210_mfd_ids,
.probe = phytium_px210_mfd_probe,
.remove = phytium_px210_mfd_remove,
};

module_pci_driver(phytium_i2s_lsd_mfd_driver);

MODULE_AUTHOR("Zhang Yiqun <[email protected]>");
MODULE_DESCRIPTION("Phytium Px210 MFD PCI driver for I2S-LSD");
MODULE_LICENSE("GPL");
185 changes: 185 additions & 0 deletions drivers/mfd/phytium_px210_i2s_mmd.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Phytium I2S MMD MFD driver over PCI bus
*
* Copyright (C) 2020-2023, Phytium Technology Co., Ltd.
*/

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/mfd/core.h>

struct phytium_px210_mfd {
struct device *dev;
};

struct pdata_px210_mfd {
struct device *dev;
char *name;
int clk_base;
};

static struct resource phytium_px210_i2s_res0[] = {
[0] = {
.flags = IORESOURCE_MEM,
},
[1] = {
.flags = IORESOURCE_MEM,
},
[2] = {
.flags = IORESOURCE_IRQ,
},
};

static struct resource phytium_px210_i2s_res1[] = {
[0] = {
.flags = IORESOURCE_MEM,
},
[1] = {
.flags = IORESOURCE_MEM,
},
[2] = {
.flags = IORESOURCE_IRQ,
},
};

static struct resource phytium_px210_i2s_res2[] = {
[0] = {
.flags = IORESOURCE_MEM,
},
[1] = {
.flags = IORESOURCE_MEM,
},
[2] = {
.flags = IORESOURCE_IRQ,
},
};

static struct mfd_cell phytium_px210_mfd_cells[] = {
{
.id = 1,
.name = "phytium-i2s",
.of_compatible = "phytium,i2s",
.resources = phytium_px210_i2s_res0,
.num_resources = ARRAY_SIZE(phytium_px210_i2s_res0),
.ignore_resource_conflicts = true,
},
{
.id = 2,
.name = "phytium-i2s",
.of_compatible = "phytium,i2s",
.resources = phytium_px210_i2s_res1,
.num_resources = ARRAY_SIZE(phytium_px210_i2s_res1),
.ignore_resource_conflicts = true,
},
{
.id = 3,
.name = "phytium-i2s",
.of_compatible = "phytium,i2s",
.resources = phytium_px210_i2s_res2,
.num_resources = ARRAY_SIZE(phytium_px210_i2s_res2),
.ignore_resource_conflicts = true,
},
};

static void phytium_px210_i2s_setup(struct pci_dev *pdev, int i)
{
struct mfd_cell *cell = &phytium_px210_mfd_cells[i];
struct resource *res = (struct resource *)cell->resources;
struct pdata_px210_mfd *pdata;

res[0].start = pci_resource_start(pdev, 0) + 0x2000 * i + 0x1000;
res[0].end = pci_resource_start(pdev, 0) + 0x2000 * i + 0x1fff;

res[1].start = pci_resource_start(pdev, 0) + 0x2000 * i;
res[1].end = pci_resource_start(pdev, 0) + 0x2000 * i + 0x0fff;

res[2].start = pdev->irq;
res[2].end = pdev->irq;

pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);

pdata->dev = &pdev->dev;
pdata->clk_base = 600000000;
switch (i) {
case 0:
pdata->name = "phytium-i2s-dp0";
break;
case 1:
pdata->name = "phytium-i2s-dp1";
break;
case 2:
pdata->name = "phytium-i2s-dp2";
break;
default:
break;
}

cell->platform_data = pdata;
cell->pdata_size = sizeof(*pdata);
}

static int phytium_px210_mfd_probe(struct pci_dev *pdev,
const struct pci_device_id *id)
{
struct phytium_px210_mfd *phytium_mfd;
int i;
int ret;

ret = pcim_enable_device(pdev);
if (ret)
return ret;

pci_set_master(pdev);

phytium_mfd = devm_kzalloc(&pdev->dev, sizeof(*phytium_mfd), GFP_KERNEL);
if (!phytium_mfd)
return -ENOMEM;

phytium_mfd->dev = &pdev->dev;
dev_set_drvdata(&pdev->dev, phytium_mfd);

for (i = 0; i < 3; i++)
phytium_px210_i2s_setup(pdev, i);

ret = mfd_add_devices(&pdev->dev, 0, phytium_px210_mfd_cells,
ARRAY_SIZE(phytium_px210_mfd_cells), NULL, 0,
NULL);
if (ret)
return 0;

return 0;
}


static void phytium_px210_mfd_remove(struct pci_dev *pdev)
{
mfd_remove_devices(&pdev->dev);
}

static const struct pci_device_id phytium_px210_mfd_ids[] = {
{
.vendor = 0x1DB7,
.device = 0xDC23,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
.class = 0x3,
.class_mask = 0,
},
{},
};
MODULE_DEVICE_TABLE(pci, phytium_px210_mfd_ids);

static struct pci_driver phytium_i2s_mmd_mfd_driver = {
.name = "phytium_px210_mfd_mmd",
.id_table = phytium_px210_mfd_ids,
.probe = phytium_px210_mfd_probe,
.remove = phytium_px210_mfd_remove,
};

module_pci_driver(phytium_i2s_mmd_mfd_driver);

MODULE_AUTHOR("Zhang Yiqun <[email protected]>");
MODULE_DESCRIPTION("Phytium Px210 MFD PCI driver for I2S-DP");
MODULE_LICENSE("GPL");
1 change: 1 addition & 0 deletions sound/soc/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ source "sound/soc/intel/Kconfig"
source "sound/soc/mediatek/Kconfig"
source "sound/soc/meson/Kconfig"
source "sound/soc/mxs/Kconfig"
source "sound/soc/phytium/Kconfig"
source "sound/soc/pxa/Kconfig"
source "sound/soc/qcom/Kconfig"
source "sound/soc/rockchip/Kconfig"
Expand Down
1 change: 1 addition & 0 deletions sound/soc/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ obj-$(CONFIG_SND_SOC) += mediatek/
obj-$(CONFIG_SND_SOC) += meson/
obj-$(CONFIG_SND_SOC) += mxs/
obj-$(CONFIG_SND_SOC) += kirkwood/
obj-$(CONFIG_SND_SOC) += phytium/
obj-$(CONFIG_SND_SOC) += pxa/
obj-$(CONFIG_SND_SOC) += qcom/
obj-$(CONFIG_SND_SOC) += rockchip/
Expand Down
9 changes: 9 additions & 0 deletions sound/soc/codecs/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -1071,6 +1071,15 @@ config SND_SOC_ES8328_SPI
depends on SPI_MASTER
select SND_SOC_ES8328

config SND_SOC_ES8336
tristate "Everest Semi ES8336 CODEC"
depends on I2C
select GPIO_PHYTIUM_PCI
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这个select是不是要去掉 ES8336 X86上也有用?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

不能去掉,这是必要的依赖。ES8336 在X86上应该是能用的,但是我们在某一款arm芯片上I2S控制器适配的是ES8336codec芯片。


config SND_SOC_ES8388
tristate "Everest Semi ES8388 CODEC"
depends on I2C

config SND_SOC_GTM601
tristate 'GTM601 UMTS modem audio codec'

Expand Down
4 changes: 4 additions & 0 deletions sound/soc/codecs/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,8 @@ snd-soc-es8326-objs := es8326.o
snd-soc-es8328-objs := es8328.o
snd-soc-es8328-i2c-objs := es8328-i2c.o
snd-soc-es8328-spi-objs := es8328-spi.o
snd-soc-es8336-objs := es8336.o
snd-soc-es8388-objs := es8388.o
snd-soc-gtm601-objs := gtm601.o
snd-soc-hdac-hdmi-objs := hdac_hdmi.o
snd-soc-hdac-hda-objs := hdac_hda.o
Expand Down Expand Up @@ -505,6 +507,8 @@ obj-$(CONFIG_SND_SOC_ES8326) += snd-soc-es8326.o
obj-$(CONFIG_SND_SOC_ES8328) += snd-soc-es8328.o
obj-$(CONFIG_SND_SOC_ES8328_I2C)+= snd-soc-es8328-i2c.o
obj-$(CONFIG_SND_SOC_ES8328_SPI)+= snd-soc-es8328-spi.o
obj-$(CONFIG_SND_SOC_ES8336)+= snd-soc-es8336.o
obj-$(CONFIG_SND_SOC_ES8388) += snd-soc-es8388.o
obj-$(CONFIG_SND_SOC_GTM601) += snd-soc-gtm601.o
obj-$(CONFIG_SND_SOC_HDAC_HDMI) += snd-soc-hdac-hdmi.o
obj-$(CONFIG_SND_SOC_HDAC_HDA) += snd-soc-hdac-hda.o
Expand Down
Loading