cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

lan9303_i2c.c (2918B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * Copyright (C) 2017 Pengutronix, Juergen Borleis <kernel@pengutronix.de>
      4 */
      5#include <linux/kernel.h>
      6#include <linux/module.h>
      7#include <linux/i2c.h>
      8#include <linux/of.h>
      9
     10#include "lan9303.h"
     11
     12struct lan9303_i2c {
     13	struct i2c_client *device;
     14	struct lan9303 chip;
     15};
     16
     17static const struct regmap_config lan9303_i2c_regmap_config = {
     18	.reg_bits = 8,
     19	.val_bits = 32,
     20	.reg_stride = 1,
     21	.can_multi_write = true,
     22	.max_register = 0x0ff, /* address bits 0..1 are not used */
     23	.reg_format_endian = REGMAP_ENDIAN_LITTLE,
     24
     25	.volatile_table = &lan9303_register_set,
     26	.wr_table = &lan9303_register_set,
     27	.rd_table = &lan9303_register_set,
     28
     29	.cache_type = REGCACHE_NONE,
     30};
     31
     32static int lan9303_i2c_probe(struct i2c_client *client,
     33			     const struct i2c_device_id *id)
     34{
     35	struct lan9303_i2c *sw_dev;
     36	int ret;
     37
     38	sw_dev = devm_kzalloc(&client->dev, sizeof(struct lan9303_i2c),
     39			      GFP_KERNEL);
     40	if (!sw_dev)
     41		return -ENOMEM;
     42
     43	sw_dev->chip.regmap = devm_regmap_init_i2c(client,
     44						   &lan9303_i2c_regmap_config);
     45	if (IS_ERR(sw_dev->chip.regmap)) {
     46		ret = PTR_ERR(sw_dev->chip.regmap);
     47		dev_err(&client->dev, "Failed to allocate register map: %d\n",
     48			ret);
     49		return ret;
     50	}
     51
     52	/* link forward and backward */
     53	sw_dev->device = client;
     54	i2c_set_clientdata(client, sw_dev);
     55	sw_dev->chip.dev = &client->dev;
     56
     57	sw_dev->chip.ops = &lan9303_indirect_phy_ops;
     58
     59	ret = lan9303_probe(&sw_dev->chip, client->dev.of_node);
     60	if (ret != 0)
     61		return ret;
     62
     63	dev_info(&client->dev, "LAN9303 I2C driver loaded successfully\n");
     64
     65	return 0;
     66}
     67
     68static int lan9303_i2c_remove(struct i2c_client *client)
     69{
     70	struct lan9303_i2c *sw_dev = i2c_get_clientdata(client);
     71
     72	if (!sw_dev)
     73		return 0;
     74
     75	lan9303_remove(&sw_dev->chip);
     76
     77	i2c_set_clientdata(client, NULL);
     78
     79	return 0;
     80}
     81
     82static void lan9303_i2c_shutdown(struct i2c_client *client)
     83{
     84	struct lan9303_i2c *sw_dev = i2c_get_clientdata(client);
     85
     86	if (!sw_dev)
     87		return;
     88
     89	lan9303_shutdown(&sw_dev->chip);
     90
     91	i2c_set_clientdata(client, NULL);
     92}
     93
     94/*-------------------------------------------------------------------------*/
     95
     96static const struct i2c_device_id lan9303_i2c_id[] = {
     97	{ "lan9303", 0 },
     98	{ /* sentinel */ }
     99};
    100MODULE_DEVICE_TABLE(i2c, lan9303_i2c_id);
    101
    102static const struct of_device_id lan9303_i2c_of_match[] = {
    103	{ .compatible = "smsc,lan9303-i2c", },
    104	{ /* sentinel */ },
    105};
    106MODULE_DEVICE_TABLE(of, lan9303_i2c_of_match);
    107
    108static struct i2c_driver lan9303_i2c_driver = {
    109	.driver = {
    110		.name = "LAN9303_I2C",
    111		.of_match_table = of_match_ptr(lan9303_i2c_of_match),
    112	},
    113	.probe = lan9303_i2c_probe,
    114	.remove = lan9303_i2c_remove,
    115	.shutdown = lan9303_i2c_shutdown,
    116	.id_table = lan9303_i2c_id,
    117};
    118module_i2c_driver(lan9303_i2c_driver);
    119
    120MODULE_AUTHOR("Juergen Borleis <kernel@pengutronix.de>");
    121MODULE_DESCRIPTION("Driver for SMSC/Microchip LAN9303 three port ethernet switch in I2C managed mode");
    122MODULE_LICENSE("GPL v2");