Blame view
drivers/mfd/wm8400-core.c
3.71 KB
2874c5fd2 treewide: Replace... |
1 |
// SPDX-License-Identifier: GPL-2.0-or-later |
1d9f9f040 mfd: Core support... |
2 3 4 5 6 7 |
/* * Core driver for WM8400. * * Copyright 2008 Wolfson Microelectronics PLC. * * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> |
1d9f9f040 mfd: Core support... |
8 |
*/ |
b2b658752 mfd: wm8400-core:... |
9 |
#include <linux/init.h> |
1d9f9f040 mfd: Core support... |
10 |
#include <linux/bug.h> |
50eeef5d3 mfd: Convert WM84... |
11 |
#include <linux/err.h> |
1d9f9f040 mfd: Core support... |
12 13 |
#include <linux/i2c.h> #include <linux/kernel.h> |
b8380c1a6 mfd: Register WM8... |
14 |
#include <linux/mfd/core.h> |
1d9f9f040 mfd: Core support... |
15 16 |
#include <linux/mfd/wm8400-private.h> #include <linux/mfd/wm8400-audio.h> |
50eeef5d3 mfd: Convert WM84... |
17 |
#include <linux/regmap.h> |
5a0e3ad6a include cleanup: ... |
18 |
#include <linux/slab.h> |
1d9f9f040 mfd: Core support... |
19 |
|
879eed682 mfd: Remove wm840... |
20 |
static bool wm8400_volatile(struct device *dev, unsigned int reg) |
1d9f9f040 mfd: Core support... |
21 |
{ |
879eed682 mfd: Remove wm840... |
22 23 24 25 26 27 28 |
switch (reg) { case WM8400_INTERRUPT_STATUS_1: case WM8400_INTERRUPT_LEVELS: case WM8400_SHUTDOWN_REASON: return true; default: return false; |
1d9f9f040 mfd: Core support... |
29 |
} |
1d9f9f040 mfd: Core support... |
30 |
} |
b8380c1a6 mfd: Register WM8... |
31 32 |
static int wm8400_register_codec(struct wm8400 *wm8400) { |
d1fb70e27 mfd: wm8400-core:... |
33 |
const struct mfd_cell cell = { |
b8380c1a6 mfd: Register WM8... |
34 |
.name = "wm8400-codec", |
e45be4b5f mfd: Use mfd cell... |
35 36 |
.platform_data = wm8400, .pdata_size = sizeof(*wm8400), |
b8380c1a6 mfd: Register WM8... |
37 |
}; |
7825dc056 mfd: wm8400: Use ... |
38 |
return devm_mfd_add_devices(wm8400->dev, -1, &cell, 1, NULL, 0, NULL); |
b8380c1a6 mfd: Register WM8... |
39 |
} |
1d9f9f040 mfd: Core support... |
40 41 42 43 44 45 46 47 48 49 |
/* * wm8400_init - Generic initialisation * * The WM8400 can be configured as either an I2C or SPI device. Probe * functions for each bus set up the accessors then call into this to * set up the device itself. */ static int wm8400_init(struct wm8400 *wm8400, struct wm8400_platform_data *pdata) { |
879eed682 mfd: Remove wm840... |
50 51 |
unsigned int reg; int ret; |
1d9f9f040 mfd: Core support... |
52 |
|
1902a9e62 mfd: remove drive... |
53 |
dev_set_drvdata(wm8400->dev, wm8400); |
1d9f9f040 mfd: Core support... |
54 55 |
/* Check that this is actually a WM8400 */ |
879eed682 mfd: Remove wm840... |
56 |
ret = regmap_read(wm8400->regmap, WM8400_RESET_ID, ®); |
1d9f9f040 mfd: Core support... |
57 58 59 60 61 |
if (ret != 0) { dev_err(wm8400->dev, "Chip ID register read failed "); return -EIO; } |
879eed682 mfd: Remove wm840... |
62 63 64 65 |
if (reg != 0x6172) { dev_err(wm8400->dev, "Device is not a WM8400, ID is %x ", reg); |
1d9f9f040 mfd: Core support... |
66 67 |
return -ENODEV; } |
879eed682 mfd: Remove wm840... |
68 |
ret = regmap_read(wm8400->regmap, WM8400_ID, ®); |
1d9f9f040 mfd: Core support... |
69 70 71 72 73 74 75 76 |
if (ret != 0) { dev_err(wm8400->dev, "ID register read failed: %d ", ret); return ret; } reg = (reg & WM8400_CHIP_REV_MASK) >> WM8400_CHIP_REV_SHIFT; dev_info(wm8400->dev, "WM8400 revision %x ", reg); |
b8380c1a6 mfd: Register WM8... |
77 78 79 80 |
ret = wm8400_register_codec(wm8400); if (ret != 0) { dev_err(wm8400->dev, "Failed to register codec "); |
7825dc056 mfd: wm8400: Use ... |
81 |
return ret; |
b8380c1a6 mfd: Register WM8... |
82 |
} |
1d9f9f040 mfd: Core support... |
83 84 |
if (pdata && pdata->platform_init) { ret = pdata->platform_init(wm8400->dev); |
b8380c1a6 mfd: Register WM8... |
85 |
if (ret != 0) { |
1d9f9f040 mfd: Core support... |
86 87 88 |
dev_err(wm8400->dev, "Platform init failed: %d ", ret); |
7825dc056 mfd: wm8400: Use ... |
89 |
return ret; |
b8380c1a6 mfd: Register WM8... |
90 |
} |
1d9f9f040 mfd: Core support... |
91 92 93 |
} else dev_warn(wm8400->dev, "No platform initialisation supplied "); |
b8380c1a6 mfd: Register WM8... |
94 |
return 0; |
1d9f9f040 mfd: Core support... |
95 |
} |
50eeef5d3 mfd: Convert WM84... |
96 97 98 99 |
static const struct regmap_config wm8400_regmap_config = { .reg_bits = 8, .val_bits = 16, .max_register = WM8400_REGISTER_COUNT - 1, |
879eed682 mfd: Remove wm840... |
100 101 102 103 |
.volatile_reg = wm8400_volatile, .cache_type = REGCACHE_RBTREE, |
50eeef5d3 mfd: Convert WM84... |
104 |
}; |
1d9f9f040 mfd: Core support... |
105 |
|
879eed682 mfd: Remove wm840... |
106 107 108 109 110 111 112 113 114 |
/** * wm8400_reset_codec_reg_cache - Reset cached codec registers to * their default values. */ void wm8400_reset_codec_reg_cache(struct wm8400 *wm8400) { regmap_reinit_cache(wm8400->regmap, &wm8400_regmap_config); } EXPORT_SYMBOL_GPL(wm8400_reset_codec_reg_cache); |
5eb519f3f mfd: Use IS_ENABL... |
115 |
#if IS_ENABLED(CONFIG_I2C) |
1d9f9f040 mfd: Core support... |
116 117 118 119 |
static int wm8400_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { struct wm8400 *wm8400; |
1d9f9f040 mfd: Core support... |
120 |
|
f57723457 mfd: Convert WM84... |
121 |
wm8400 = devm_kzalloc(&i2c->dev, sizeof(struct wm8400), GFP_KERNEL); |
82ae61c4b mfd: wm8400-core:... |
122 123 |
if (!wm8400) return -ENOMEM; |
1d9f9f040 mfd: Core support... |
124 |
|
2b40e9d97 mfd: wm8400: Conv... |
125 |
wm8400->regmap = devm_regmap_init_i2c(i2c, &wm8400_regmap_config); |
82ae61c4b mfd: wm8400-core:... |
126 127 |
if (IS_ERR(wm8400->regmap)) return PTR_ERR(wm8400->regmap); |
50eeef5d3 mfd: Convert WM84... |
128 |
|
1d9f9f040 mfd: Core support... |
129 130 |
wm8400->dev = &i2c->dev; i2c_set_clientdata(i2c, wm8400); |
82ae61c4b mfd: wm8400-core:... |
131 |
return wm8400_init(wm8400, dev_get_platdata(&i2c->dev)); |
1d9f9f040 mfd: Core support... |
132 |
} |
1d9f9f040 mfd: Core support... |
133 134 135 136 |
static const struct i2c_device_id wm8400_i2c_id[] = { { "wm8400", 0 }, { } }; |
1d9f9f040 mfd: Core support... |
137 138 139 140 |
static struct i2c_driver wm8400_i2c_driver = { .driver = { .name = "WM8400", |
1d9f9f040 mfd: Core support... |
141 142 |
}, .probe = wm8400_i2c_probe, |
1d9f9f040 mfd: Core support... |
143 144 145 |
.id_table = wm8400_i2c_id, }; #endif |
b2b658752 mfd: wm8400-core:... |
146 |
static int __init wm8400_driver_init(void) |
1d9f9f040 mfd: Core support... |
147 148 |
{ int ret = -ENODEV; |
5eb519f3f mfd: Use IS_ENABL... |
149 |
#if IS_ENABLED(CONFIG_I2C) |
1d9f9f040 mfd: Core support... |
150 151 152 153 154 155 156 157 |
ret = i2c_add_driver(&wm8400_i2c_driver); if (ret != 0) pr_err("Failed to register I2C driver: %d ", ret); #endif return ret; } |
b2b658752 mfd: wm8400-core:... |
158 |
subsys_initcall(wm8400_driver_init); |