2 * Copyright (C) 2014 Free Electrons
3 * Copyright (C) 2014 Atmel
5 * Author: Boris BREZILLON <boris.brezillon@free-electrons.com>
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.
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
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/>.
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>
27 #define ATMEL_HLCDC_REG_MAX (0x4000 - 0x4)
29 static const struct mfd_cell atmel_hlcdc_cells
[] = {
31 .name
= "atmel-hlcdc-pwm",
32 .of_compatible
= "atmel,hlcdc-pwm",
35 .name
= "atmel-hlcdc-dc",
36 .of_compatible
= "atmel,hlcdc-display-controller",
40 static const struct regmap_config atmel_hlcdc_regmap_config
= {
44 .max_register
= ATMEL_HLCDC_REG_MAX
,
47 static int atmel_hlcdc_probe(struct platform_device
*pdev
)
49 struct device
*dev
= &pdev
->dev
;
50 struct atmel_hlcdc
*hlcdc
;
54 hlcdc
= devm_kzalloc(dev
, sizeof(*hlcdc
), GFP_KERNEL
);
58 res
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
59 regs
= devm_ioremap_resource(dev
, res
);
63 hlcdc
->irq
= platform_get_irq(pdev
, 0);
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
);
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
);
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
);
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
);
90 dev_set_drvdata(dev
, hlcdc
);
92 return mfd_add_devices(dev
, -1, atmel_hlcdc_cells
,
93 ARRAY_SIZE(atmel_hlcdc_cells
),
97 static int atmel_hlcdc_remove(struct platform_device
*pdev
)
99 mfd_remove_devices(&pdev
->dev
);
104 static const struct of_device_id atmel_hlcdc_match
[] = {
105 { .compatible
= "atmel,sama5d3-hlcdc" },
109 static struct platform_driver atmel_hlcdc_driver
= {
110 .probe
= atmel_hlcdc_probe
,
111 .remove
= atmel_hlcdc_remove
,
113 .name
= "atmel-hlcdc",
114 .of_match_table
= atmel_hlcdc_match
,
117 module_platform_driver(atmel_hlcdc_driver
);
119 MODULE_ALIAS("platform:atmel-hlcdc");
120 MODULE_AUTHOR("Boris Brezillon <boris.brezillon@free-electrons.com>");
121 MODULE_DESCRIPTION("Atmel HLCDC driver");
122 MODULE_LICENSE("GPL v2");