linux/drivers/mfd/wm831x-spi.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-or-later
   2/*
   3 * wm831x-spi.c  --  SPI access for Wolfson WM831x PMICs
   4 *
   5 * Copyright 2009,2010 Wolfson Microelectronics PLC.
   6 *
   7 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
   8 */
   9
  10#include <linux/kernel.h>
  11#include <linux/init.h>
  12#include <linux/of.h>
  13#include <linux/of_device.h>
  14#include <linux/pm.h>
  15#include <linux/spi/spi.h>
  16#include <linux/regmap.h>
  17#include <linux/err.h>
  18
  19#include <linux/mfd/wm831x/core.h>
  20
  21static int wm831x_spi_probe(struct spi_device *spi)
  22{
  23        struct wm831x_pdata *pdata = dev_get_platdata(&spi->dev);
  24        const struct spi_device_id *id = spi_get_device_id(spi);
  25        const struct of_device_id *of_id;
  26        struct wm831x *wm831x;
  27        enum wm831x_parent type;
  28        int ret;
  29
  30        if (spi->dev.of_node) {
  31                of_id = of_match_device(wm831x_of_match, &spi->dev);
  32                if (!of_id) {
  33                        dev_err(&spi->dev, "Failed to match device\n");
  34                        return -ENODEV;
  35                }
  36                type = (enum wm831x_parent)of_id->data;
  37        } else {
  38                type = (enum wm831x_parent)id->driver_data;
  39        }
  40
  41        wm831x = devm_kzalloc(&spi->dev, sizeof(struct wm831x), GFP_KERNEL);
  42        if (wm831x == NULL)
  43                return -ENOMEM;
  44
  45        spi->mode = SPI_MODE_0;
  46
  47        spi_set_drvdata(spi, wm831x);
  48        wm831x->dev = &spi->dev;
  49        wm831x->type = type;
  50
  51        wm831x->regmap = devm_regmap_init_spi(spi, &wm831x_regmap_config);
  52        if (IS_ERR(wm831x->regmap)) {
  53                ret = PTR_ERR(wm831x->regmap);
  54                dev_err(wm831x->dev, "Failed to allocate register map: %d\n",
  55                        ret);
  56                return ret;
  57        }
  58
  59        if (pdata)
  60                memcpy(&wm831x->pdata, pdata, sizeof(*pdata));
  61
  62        return wm831x_device_init(wm831x, spi->irq);
  63}
  64
  65static int wm831x_spi_suspend(struct device *dev)
  66{
  67        struct wm831x *wm831x = dev_get_drvdata(dev);
  68
  69        return wm831x_device_suspend(wm831x);
  70}
  71
  72static int wm831x_spi_poweroff(struct device *dev)
  73{
  74        struct wm831x *wm831x = dev_get_drvdata(dev);
  75
  76        wm831x_device_shutdown(wm831x);
  77
  78        return 0;
  79}
  80
  81static const struct dev_pm_ops wm831x_spi_pm = {
  82        .freeze = wm831x_spi_suspend,
  83        .suspend = wm831x_spi_suspend,
  84        .poweroff = wm831x_spi_poweroff,
  85};
  86
  87static const struct spi_device_id wm831x_spi_ids[] = {
  88        { "wm8310", WM8310 },
  89        { "wm8311", WM8311 },
  90        { "wm8312", WM8312 },
  91        { "wm8320", WM8320 },
  92        { "wm8321", WM8321 },
  93        { "wm8325", WM8325 },
  94        { "wm8326", WM8326 },
  95        { },
  96};
  97
  98static struct spi_driver wm831x_spi_driver = {
  99        .driver = {
 100                .name   = "wm831x",
 101                .pm     = &wm831x_spi_pm,
 102                .of_match_table = of_match_ptr(wm831x_of_match),
 103                .suppress_bind_attrs = true,
 104        },
 105        .id_table       = wm831x_spi_ids,
 106        .probe          = wm831x_spi_probe,
 107};
 108
 109static int __init wm831x_spi_init(void)
 110{
 111        int ret;
 112
 113        ret = spi_register_driver(&wm831x_spi_driver);
 114        if (ret != 0)
 115                pr_err("Failed to register WM831x SPI driver: %d\n", ret);
 116
 117        return 0;
 118}
 119subsys_initcall(wm831x_spi_init);
 120