aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/mfd/Kconfig6
-rw-r--r--drivers/mfd/Makefile1
-rw-r--r--drivers/mfd/atmel-hlcdc.c122
-rw-r--r--include/linux/mfd/atmel-hlcdc.h85
4 files changed, 214 insertions, 0 deletions
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index fdbb40181834..bd4a155a9564 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -59,6 +59,12 @@ config MFD_AAT2870_CORE
59 additional drivers must be enabled in order to use the 59 additional drivers must be enabled in order to use the
60 functionality of the device. 60 functionality of the device.
61 61
62config MFD_ATMEL_HLCDC
63 tristate
64 select MFD_CORE
65 select REGMAP_MMIO
66 depends on OF
67
62config MFD_BCM590XX 68config MFD_BCM590XX
63 tristate "Broadcom BCM590xx PMUs" 69 tristate "Broadcom BCM590xx PMUs"
64 select MFD_CORE 70 select MFD_CORE
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index 10bbd0b9096b..2cd7e743280c 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -157,6 +157,7 @@ obj-$(CONFIG_MFD_SPMI_PMIC) += qcom-spmi-pmic.o
157obj-$(CONFIG_TPS65911_COMPARATOR) += tps65911-comparator.o 157obj-$(CONFIG_TPS65911_COMPARATOR) += tps65911-comparator.o
158obj-$(CONFIG_MFD_TPS65090) += tps65090.o 158obj-$(CONFIG_MFD_TPS65090) += tps65090.o
159obj-$(CONFIG_MFD_AAT2870_CORE) += aat2870-core.o 159obj-$(CONFIG_MFD_AAT2870_CORE) += aat2870-core.o
160obj-$(CONFIG_MFD_ATMEL_HLCDC) += atmel-hlcdc.o
160obj-$(CONFIG_MFD_INTEL_MSIC) += intel_msic.o 161obj-$(CONFIG_MFD_INTEL_MSIC) += intel_msic.o
161obj-$(CONFIG_MFD_PALMAS) += palmas.o 162obj-$(CONFIG_MFD_PALMAS) += palmas.o
162obj-$(CONFIG_MFD_VIPERBOARD) += viperboard.o 163obj-$(CONFIG_MFD_VIPERBOARD) += viperboard.o
diff --git a/drivers/mfd/atmel-hlcdc.c b/drivers/mfd/atmel-hlcdc.c
new file mode 100644
index 000000000000..cfd58f4cc5c3
--- /dev/null
+++ b/drivers/mfd/atmel-hlcdc.c
@@ -0,0 +1,122 @@
1/*
2 * Copyright (C) 2014 Free Electrons
3 * Copyright (C) 2014 Atmel
4 *
5 * Author: Boris BREZILLON <boris.brezillon@free-electrons.com>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License version 2 as published by
9 * the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details.
15 *
16 * You should have received a copy of the GNU General Public License along with
17 * this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include <linux/clk.h>
21#include <linux/mfd/atmel-hlcdc.h>
22#include <linux/mfd/core.h>
23#include <linux/module.h>
24#include <linux/platform_device.h>
25#include <linux/regmap.h>
26
27#define ATMEL_HLCDC_REG_MAX (0x4000 - 0x4)
28
29static const struct mfd_cell atmel_hlcdc_cells[] = {
30 {
31 .name = "atmel-hlcdc-pwm",
32 .of_compatible = "atmel,hlcdc-pwm",
33 },
34 {
35 .name = "atmel-hlcdc-dc",
36 .of_compatible = "atmel,hlcdc-display-controller",
37 },
38};
39
40static const struct regmap_config atmel_hlcdc_regmap_config = {
41 .reg_bits = 32,
42 .val_bits = 32,
43 .reg_stride = 4,
44 .max_register = ATMEL_HLCDC_REG_MAX,
45};
46
47static int atmel_hlcdc_probe(struct platform_device *pdev)
48{
49 struct device *dev = &pdev->dev;
50 struct atmel_hlcdc *hlcdc;
51 struct resource *res;
52 void __iomem *regs;
53
54 hlcdc = devm_kzalloc(dev, sizeof(*hlcdc), GFP_KERNEL);
55 if (!hlcdc)
56 return -ENOMEM;
57
58 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
59 regs = devm_ioremap_resource(dev, res);
60 if (IS_ERR(regs))
61 return PTR_ERR(regs);
62
63 hlcdc->irq = platform_get_irq(pdev, 0);
64 if (hlcdc->irq < 0)
65 return hlcdc->irq;
66
67 hlcdc->periph_clk = devm_clk_get(dev, "periph_clk");
68 if (IS_ERR(hlcdc->periph_clk)) {
69 dev_err(dev, "failed to get peripheral clock\n");
70 return PTR_ERR(hlcdc->periph_clk);
71 }
72
73 hlcdc->sys_clk = devm_clk_get(dev, "sys_clk");
74 if (IS_ERR(hlcdc->sys_clk)) {
75 dev_err(dev, "failed to get system clock\n");
76 return PTR_ERR(hlcdc->sys_clk);
77 }
78
79 hlcdc->slow_clk = devm_clk_get(dev, "slow_clk");
80 if (IS_ERR(hlcdc->slow_clk)) {
81 dev_err(dev, "failed to get slow clock\n");
82 return PTR_ERR(hlcdc->slow_clk);
83 }
84
85 hlcdc->regmap = devm_regmap_init_mmio(dev, regs,
86 &atmel_hlcdc_regmap_config);
87 if (IS_ERR(hlcdc->regmap))
88 return PTR_ERR(hlcdc->regmap);
89
90 dev_set_drvdata(dev, hlcdc);
91
92 return mfd_add_devices(dev, -1, atmel_hlcdc_cells,
93 ARRAY_SIZE(atmel_hlcdc_cells),
94 NULL, 0, NULL);
95}
96
97static int atmel_hlcdc_remove(struct platform_device *pdev)
98{
99 mfd_remove_devices(&pdev->dev);
100
101 return 0;
102}
103
104static const struct of_device_id atmel_hlcdc_match[] = {
105 { .compatible = "atmel,sama5d3-hlcdc" },
106 { /* sentinel */ },
107};
108
109static struct platform_driver atmel_hlcdc_driver = {
110 .probe = atmel_hlcdc_probe,
111 .remove = atmel_hlcdc_remove,
112 .driver = {
113 .name = "atmel-hlcdc",
114 .of_match_table = atmel_hlcdc_match,
115 },
116};
117module_platform_driver(atmel_hlcdc_driver);
118
119MODULE_ALIAS("platform:atmel-hlcdc");
120MODULE_AUTHOR("Boris Brezillon <boris.brezillon@free-electrons.com>");
121MODULE_DESCRIPTION("Atmel HLCDC driver");
122MODULE_LICENSE("GPL v2");
diff --git a/include/linux/mfd/atmel-hlcdc.h b/include/linux/mfd/atmel-hlcdc.h
new file mode 100644
index 000000000000..1279ab1644b5
--- /dev/null
+++ b/include/linux/mfd/atmel-hlcdc.h
@@ -0,0 +1,85 @@
1/*
2 * Copyright (C) 2014 Free Electrons
3 * Copyright (C) 2014 Atmel
4 *
5 * Author: Boris BREZILLON <boris.brezillon@free-electrons.com>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License version 2 as published by
9 * the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details.
15 *
16 * You should have received a copy of the GNU General Public License along with
17 * this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#ifndef __LINUX_MFD_HLCDC_H
21#define __LINUX_MFD_HLCDC_H
22
23#include <linux/clk.h>
24#include <linux/regmap.h>
25
26#define ATMEL_HLCDC_CFG(i) ((i) * 0x4)
27#define ATMEL_HLCDC_SIG_CFG LCDCFG(5)
28#define ATMEL_HLCDC_HSPOL BIT(0)
29#define ATMEL_HLCDC_VSPOL BIT(1)
30#define ATMEL_HLCDC_VSPDLYS BIT(2)
31#define ATMEL_HLCDC_VSPDLYE BIT(3)
32#define ATMEL_HLCDC_DISPPOL BIT(4)
33#define ATMEL_HLCDC_DITHER BIT(6)
34#define ATMEL_HLCDC_DISPDLY BIT(7)
35#define ATMEL_HLCDC_MODE_MASK GENMASK(9, 8)
36#define ATMEL_HLCDC_PP BIT(10)
37#define ATMEL_HLCDC_VSPSU BIT(12)
38#define ATMEL_HLCDC_VSPHO BIT(13)
39#define ATMEL_HLCDC_GUARDTIME_MASK GENMASK(20, 16)
40
41#define ATMEL_HLCDC_EN 0x20
42#define ATMEL_HLCDC_DIS 0x24
43#define ATMEL_HLCDC_SR 0x28
44#define ATMEL_HLCDC_IER 0x2c
45#define ATMEL_HLCDC_IDR 0x30
46#define ATMEL_HLCDC_IMR 0x34
47#define ATMEL_HLCDC_ISR 0x38
48
49#define ATMEL_HLCDC_CLKPOL BIT(0)
50#define ATMEL_HLCDC_CLKSEL BIT(2)
51#define ATMEL_HLCDC_CLKPWMSEL BIT(3)
52#define ATMEL_HLCDC_CGDIS(i) BIT(8 + (i))
53#define ATMEL_HLCDC_CLKDIV_SHFT 16
54#define ATMEL_HLCDC_CLKDIV_MASK GENMASK(23, 16)
55#define ATMEL_HLCDC_CLKDIV(div) ((div - 2) << ATMEL_HLCDC_CLKDIV_SHFT)
56
57#define ATMEL_HLCDC_PIXEL_CLK BIT(0)
58#define ATMEL_HLCDC_SYNC BIT(1)
59#define ATMEL_HLCDC_DISP BIT(2)
60#define ATMEL_HLCDC_PWM BIT(3)
61#define ATMEL_HLCDC_SIP BIT(4)
62
63#define ATMEL_HLCDC_SOF BIT(0)
64#define ATMEL_HLCDC_SYNCDIS BIT(1)
65#define ATMEL_HLCDC_FIFOERR BIT(4)
66#define ATMEL_HLCDC_LAYER_STATUS(x) BIT((x) + 8)
67
68/**
69 * Structure shared by the MFD device and its subdevices.
70 *
71 * @regmap: register map used to access HLCDC IP registers
72 * @periph_clk: the hlcdc peripheral clock
73 * @sys_clk: the hlcdc system clock
74 * @slow_clk: the system slow clk
75 * @irq: the hlcdc irq
76 */
77struct atmel_hlcdc {
78 struct regmap *regmap;
79 struct clk *periph_clk;
80 struct clk *sys_clk;
81 struct clk *slow_clk;
82 int irq;
83};
84
85#endif /* __LINUX_MFD_HLCDC_H */