cregit-Linux how code gets into the kernel

Release 4.16 drivers/net/phy/mdio-i2c.c

Directory: drivers/net/phy
/*
 * MDIO I2C bridge
 *
 * Copyright (C) 2015-2016 Russell King
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 *
 * Network PHYs can appear on I2C buses when they are part of SFP module.
 * This driver exposes these PHYs to the networking PHY code, allowing
 * our PHY drivers access to these PHYs, and so allowing configuration
 * of their settings.
 */
#include <linux/i2c.h>
#include <linux/phy.h>

#include "mdio-i2c.h"

/*
 * I2C bus addresses 0x50 and 0x51 are normally an EEPROM, which is
 * specified to be present in SFP modules.  These correspond with PHY
 * addresses 16 and 17.  Disallow access to these "phy" addresses.
 */

static bool i2c_mii_valid_phy_id(int phy_id) { return phy_id != 0x10 && phy_id != 0x11; }

Contributors

PersonTokensPropCommitsCommitProp
Russell King18100.00%1100.00%
Total18100.00%1100.00%


static unsigned int i2c_mii_phy_addr(int phy_id) { return phy_id + 0x40; }

Contributors

PersonTokensPropCommitsCommitProp
Russell King15100.00%1100.00%
Total15100.00%1100.00%


static int i2c_mii_read(struct mii_bus *bus, int phy_id, int reg) { struct i2c_adapter *i2c = bus->priv; struct i2c_msg msgs[2]; u8 data[2], dev_addr = reg; int bus_addr, ret; if (!i2c_mii_valid_phy_id(phy_id)) return 0xffff; bus_addr = i2c_mii_phy_addr(phy_id); msgs[0].addr = bus_addr; msgs[0].flags = 0; msgs[0].len = 1; msgs[0].buf = &dev_addr; msgs[1].addr = bus_addr; msgs[1].flags = I2C_M_RD; msgs[1].len = sizeof(data); msgs[1].buf = data; ret = i2c_transfer(i2c, msgs, ARRAY_SIZE(msgs)); if (ret != ARRAY_SIZE(msgs)) return 0xffff; return data[0] << 8 | data[1]; }

Contributors

PersonTokensPropCommitsCommitProp
Russell King181100.00%1100.00%
Total181100.00%1100.00%


static int i2c_mii_write(struct mii_bus *bus, int phy_id, int reg, u16 val) { struct i2c_adapter *i2c = bus->priv; struct i2c_msg msg; int ret; u8 data[3]; if (!i2c_mii_valid_phy_id(phy_id)) return 0; data[0] = reg; data[1] = val >> 8; data[2] = val; msg.addr = i2c_mii_phy_addr(phy_id); msg.flags = 0; msg.len = 3; msg.buf = data; ret = i2c_transfer(i2c, &msg, 1); return ret < 0 ? ret : 0; }

Contributors

PersonTokensPropCommitsCommitProp
Russell King124100.00%1100.00%
Total124100.00%1100.00%


struct mii_bus *mdio_i2c_alloc(struct device *parent, struct i2c_adapter *i2c) { struct mii_bus *mii; if (!i2c_check_functionality(i2c, I2C_FUNC_I2C)) return ERR_PTR(-EINVAL); mii = mdiobus_alloc(); if (!mii) return ERR_PTR(-ENOMEM); snprintf(mii->id, MII_BUS_ID_SIZE, "i2c:%s", dev_name(parent)); mii->parent = parent; mii->read = i2c_mii_read; mii->write = i2c_mii_write; mii->priv = i2c; return mii; }

Contributors

PersonTokensPropCommitsCommitProp
Russell King99100.00%1100.00%
Total99100.00%1100.00%

EXPORT_SYMBOL_GPL(mdio_i2c_alloc); MODULE_AUTHOR("Russell King"); MODULE_DESCRIPTION("MDIO I2C bridge library"); MODULE_LICENSE("GPL v2");

Overall Contributors

PersonTokensPropCommitsCommitProp
Russell King468100.00%1100.00%
Total468100.00%1100.00%
Directory: drivers/net/phy
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
Created with cregit.