Pull i2c updates from Wolfram Sang: - 'remove' callback converted to return void. Big change with trivial fixes all over the tree. Other subsystems depending on this change have been asked to pull an immutable topic branch for this. - new driver for Microchip PCI1xxxx switch - heavy refactoring of the Mellanox BlueField driver - we prefer async probe in the i801 driver now - the rest is usual driver updates (support for more SoCs, some refactoring, some feature additions) * tag 'i2c-for-6.1-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux: (37 commits) i2c: pci1xxxx: prevent signed integer overflow i2c: acpi: Replace zero-length array with DECLARE_FLEX_ARRAY() helper i2c: i801: Prefer async probe i2c: designware-pci: Use standard pattern for memory allocation i2c: designware-pci: Group AMD NAVI quirk parts together i2c: microchip: pci1xxxx: Add driver for I2C host controller in multifunction endpoint of pci1xxxx switch docs: i2c: slave-interface: return errno when handle I2C_SLAVE_WRITE_REQUESTED i2c: mlxbf: remove device tree support i2c: mlxbf: support BlueField-3 SoC i2c: cadence: Add standard bus recovery support i2c: mlxbf: add multi slave functionality i2c: mlxbf: support lock mechanism macintosh/ams: Adapt declaration of ams_i2c_remove() to earlier change i2c: riic: Use devm_platform_ioremap_resource() i2c: mlxbf: remove IRQF_ONESHOT dt-bindings: i2c: rockchip: add rockchip,rk3128-i2c dt-bindings: i2c: renesas,rcar-i2c: Add r8a779g0 support i2c: tegra: Add GPCDMA support i2c: scmi: Convert to be a platform driver i2c: rk3x: Add rv1126 support ...
119 lines
2.8 KiB
C
119 lines
2.8 KiB
C
// SPDX-License-Identifier: GPL-2.0-only
|
|
/*
|
|
* Copyright (C) 2017 Pengutronix, Juergen Borleis <kernel@pengutronix.de>
|
|
*/
|
|
#include <linux/kernel.h>
|
|
#include <linux/module.h>
|
|
#include <linux/i2c.h>
|
|
#include <linux/of.h>
|
|
|
|
#include "lan9303.h"
|
|
|
|
struct lan9303_i2c {
|
|
struct i2c_client *device;
|
|
struct lan9303 chip;
|
|
};
|
|
|
|
static const struct regmap_config lan9303_i2c_regmap_config = {
|
|
.reg_bits = 8,
|
|
.val_bits = 32,
|
|
.reg_stride = 1,
|
|
.can_multi_write = true,
|
|
.max_register = 0x0ff, /* address bits 0..1 are not used */
|
|
.reg_format_endian = REGMAP_ENDIAN_LITTLE,
|
|
|
|
.volatile_table = &lan9303_register_set,
|
|
.wr_table = &lan9303_register_set,
|
|
.rd_table = &lan9303_register_set,
|
|
|
|
.cache_type = REGCACHE_NONE,
|
|
};
|
|
|
|
static int lan9303_i2c_probe(struct i2c_client *client,
|
|
const struct i2c_device_id *id)
|
|
{
|
|
struct lan9303_i2c *sw_dev;
|
|
int ret;
|
|
|
|
sw_dev = devm_kzalloc(&client->dev, sizeof(struct lan9303_i2c),
|
|
GFP_KERNEL);
|
|
if (!sw_dev)
|
|
return -ENOMEM;
|
|
|
|
sw_dev->chip.regmap = devm_regmap_init_i2c(client,
|
|
&lan9303_i2c_regmap_config);
|
|
if (IS_ERR(sw_dev->chip.regmap)) {
|
|
ret = PTR_ERR(sw_dev->chip.regmap);
|
|
dev_err(&client->dev, "Failed to allocate register map: %d\n",
|
|
ret);
|
|
return ret;
|
|
}
|
|
|
|
/* link forward and backward */
|
|
sw_dev->device = client;
|
|
i2c_set_clientdata(client, sw_dev);
|
|
sw_dev->chip.dev = &client->dev;
|
|
|
|
sw_dev->chip.ops = &lan9303_indirect_phy_ops;
|
|
|
|
ret = lan9303_probe(&sw_dev->chip, client->dev.of_node);
|
|
if (ret != 0)
|
|
return ret;
|
|
|
|
dev_info(&client->dev, "LAN9303 I2C driver loaded successfully\n");
|
|
|
|
return 0;
|
|
}
|
|
|
|
static void lan9303_i2c_remove(struct i2c_client *client)
|
|
{
|
|
struct lan9303_i2c *sw_dev = i2c_get_clientdata(client);
|
|
|
|
if (!sw_dev)
|
|
return;
|
|
|
|
lan9303_remove(&sw_dev->chip);
|
|
}
|
|
|
|
static void lan9303_i2c_shutdown(struct i2c_client *client)
|
|
{
|
|
struct lan9303_i2c *sw_dev = i2c_get_clientdata(client);
|
|
|
|
if (!sw_dev)
|
|
return;
|
|
|
|
lan9303_shutdown(&sw_dev->chip);
|
|
|
|
i2c_set_clientdata(client, NULL);
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
|
|
static const struct i2c_device_id lan9303_i2c_id[] = {
|
|
{ "lan9303", 0 },
|
|
{ /* sentinel */ }
|
|
};
|
|
MODULE_DEVICE_TABLE(i2c, lan9303_i2c_id);
|
|
|
|
static const struct of_device_id lan9303_i2c_of_match[] = {
|
|
{ .compatible = "smsc,lan9303-i2c", },
|
|
{ /* sentinel */ },
|
|
};
|
|
MODULE_DEVICE_TABLE(of, lan9303_i2c_of_match);
|
|
|
|
static struct i2c_driver lan9303_i2c_driver = {
|
|
.driver = {
|
|
.name = "LAN9303_I2C",
|
|
.of_match_table = of_match_ptr(lan9303_i2c_of_match),
|
|
},
|
|
.probe = lan9303_i2c_probe,
|
|
.remove = lan9303_i2c_remove,
|
|
.shutdown = lan9303_i2c_shutdown,
|
|
.id_table = lan9303_i2c_id,
|
|
};
|
|
module_i2c_driver(lan9303_i2c_driver);
|
|
|
|
MODULE_AUTHOR("Juergen Borleis <kernel@pengutronix.de>");
|
|
MODULE_DESCRIPTION("Driver for SMSC/Microchip LAN9303 three port ethernet switch in I2C managed mode");
|
|
MODULE_LICENSE("GPL v2");
|