cregit-Linux how code gets into the kernel

Release 4.11 drivers/net/dsa/b53/b53_spi.c

/*
 * B53 register access through SPI
 *
 * Copyright (C) 2011-2013 Jonas Gorski <jogo@openwrt.org>
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#include <asm/unaligned.h>

#include <linux/delay.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/spi/spi.h>
#include <linux/platform_data/b53.h>

#include "b53_priv.h"


#define B53_SPI_DATA		0xf0


#define B53_SPI_STATUS		0xfe

#define B53_SPI_CMD_SPIF	BIT(7)

#define B53_SPI_CMD_RACK	BIT(5)


#define B53_SPI_CMD_READ	0x00

#define B53_SPI_CMD_WRITE	0x01

#define B53_SPI_CMD_NORMAL	0x60

#define B53_SPI_CMD_FAST	0x10


#define B53_SPI_PAGE_SELECT	0xff


static inline int b53_spi_read_reg(struct spi_device *spi, u8 reg, u8 *val, unsigned int len) { u8 txbuf[2]; txbuf[0] = B53_SPI_CMD_NORMAL | B53_SPI_CMD_READ; txbuf[1] = reg; return spi_write_then_read(spi, txbuf, 2, val, len); }

Contributors

PersonTokensPropCommitsCommitProp
Florian Fainelli59100.00%1100.00%
Total59100.00%1100.00%


static inline int b53_spi_clear_status(struct spi_device *spi) { unsigned int i; u8 rxbuf; int ret; for (i = 0; i < 10; i++) { ret = b53_spi_read_reg(spi, B53_SPI_STATUS, &rxbuf, 1); if (ret) return ret; if (!(rxbuf & B53_SPI_CMD_SPIF)) break; mdelay(1); } if (i == 10) return -EIO; return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Florian Fainelli86100.00%1100.00%
Total86100.00%1100.00%


static inline int b53_spi_set_page(struct spi_device *spi, u8 page) { u8 txbuf[3]; txbuf[0] = B53_SPI_CMD_NORMAL | B53_SPI_CMD_WRITE; txbuf[1] = B53_SPI_PAGE_SELECT; txbuf[2] = page; return spi_write(spi, txbuf, sizeof(txbuf)); }

Contributors

PersonTokensPropCommitsCommitProp
Florian Fainelli57100.00%1100.00%
Total57100.00%1100.00%


static inline int b53_prepare_reg_access(struct spi_device *spi, u8 page) { int ret = b53_spi_clear_status(spi); if (ret) return ret; return b53_spi_set_page(spi, page); }

Contributors

PersonTokensPropCommitsCommitProp
Florian Fainelli38100.00%1100.00%
Total38100.00%1100.00%


static int b53_spi_prepare_reg_read(struct spi_device *spi, u8 reg) { u8 rxbuf; int retry_count; int ret; ret = b53_spi_read_reg(spi, reg, &rxbuf, 1); if (ret) return ret; for (retry_count = 0; retry_count < 10; retry_count++) { ret = b53_spi_read_reg(spi, B53_SPI_STATUS, &rxbuf, 1); if (ret) return ret; if (rxbuf & B53_SPI_CMD_RACK) break; mdelay(1); } if (retry_count == 10) return -EIO; return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Florian Fainelli105100.00%1100.00%
Total105100.00%1100.00%


static int b53_spi_read(struct b53_device *dev, u8 page, u8 reg, u8 *data, unsigned int len) { struct spi_device *spi = dev->priv; int ret; ret = b53_prepare_reg_access(spi, page); if (ret) return ret; ret = b53_spi_prepare_reg_read(spi, reg); if (ret) return ret; return b53_spi_read_reg(spi, B53_SPI_DATA, data, len); }

Contributors

PersonTokensPropCommitsCommitProp
Florian Fainelli81100.00%1100.00%
Total81100.00%1100.00%


static int b53_spi_read8(struct b53_device *dev, u8 page, u8 reg, u8 *val) { return b53_spi_read(dev, page, reg, val, 1); }

Contributors

PersonTokensPropCommitsCommitProp
Florian Fainelli35100.00%1100.00%
Total35100.00%1100.00%


static int b53_spi_read16(struct b53_device *dev, u8 page, u8 reg, u16 *val) { int ret = b53_spi_read(dev, page, reg, (u8 *)val, 2); if (!ret) *val = le16_to_cpu(*val); return ret; }

Contributors

PersonTokensPropCommitsCommitProp
Florian Fainelli58100.00%1100.00%
Total58100.00%1100.00%


static int b53_spi_read32(struct b53_device *dev, u8 page, u8 reg, u32 *val) { int ret = b53_spi_read(dev, page, reg, (u8 *)val, 4); if (!ret) *val = le32_to_cpu(*val); return ret; }

Contributors

PersonTokensPropCommitsCommitProp
Florian Fainelli58100.00%1100.00%
Total58100.00%1100.00%


static int b53_spi_read48(struct b53_device *dev, u8 page, u8 reg, u64 *val) { int ret; *val = 0; ret = b53_spi_read(dev, page, reg, (u8 *)val, 6); if (!ret) *val = le64_to_cpu(*val); return ret; }

Contributors

PersonTokensPropCommitsCommitProp
Florian Fainelli65100.00%1100.00%
Total65100.00%1100.00%


static int b53_spi_read64(struct b53_device *dev, u8 page, u8 reg, u64 *val) { int ret = b53_spi_read(dev, page, reg, (u8 *)val, 8); if (!ret) *val = le64_to_cpu(*val); return ret; }

Contributors

PersonTokensPropCommitsCommitProp
Florian Fainelli58100.00%1100.00%
Total58100.00%1100.00%


static int b53_spi_write8(struct b53_device *dev, u8 page, u8 reg, u8 value) { struct spi_device *spi = dev->priv; int ret; u8 txbuf[3]; ret = b53_prepare_reg_access(spi, page); if (ret) return ret; txbuf[0] = B53_SPI_CMD_NORMAL | B53_SPI_CMD_WRITE; txbuf[1] = reg; txbuf[2] = value; return spi_write(spi, txbuf, sizeof(txbuf)); }

Contributors

PersonTokensPropCommitsCommitProp
Florian Fainelli90100.00%1100.00%
Total90100.00%1100.00%


static int b53_spi_write16(struct b53_device *dev, u8 page, u8 reg, u16 value) { struct spi_device *spi = dev->priv; int ret; u8 txbuf[4]; ret = b53_prepare_reg_access(spi, page); if (ret) return ret; txbuf[0] = B53_SPI_CMD_NORMAL | B53_SPI_CMD_WRITE; txbuf[1] = reg; put_unaligned_le16(value, &txbuf[2]); return spi_write(spi, txbuf, sizeof(txbuf)); }

Contributors

PersonTokensPropCommitsCommitProp
Florian Fainelli94100.00%1100.00%
Total94100.00%1100.00%


static int b53_spi_write32(struct b53_device *dev, u8 page, u8 reg, u32 value) { struct spi_device *spi = dev->priv; int ret; u8 txbuf[6]; ret = b53_prepare_reg_access(spi, page); if (ret) return ret; txbuf[0] = B53_SPI_CMD_NORMAL | B53_SPI_CMD_WRITE; txbuf[1] = reg; put_unaligned_le32(value, &txbuf[2]); return spi_write(spi, txbuf, sizeof(txbuf)); }

Contributors

PersonTokensPropCommitsCommitProp
Florian Fainelli94100.00%1100.00%
Total94100.00%1100.00%


static int b53_spi_write48(struct b53_device *dev, u8 page, u8 reg, u64 value) { struct spi_device *spi = dev->priv; int ret; u8 txbuf[10]; ret = b53_prepare_reg_access(spi, page); if (ret) return ret; txbuf[0] = B53_SPI_CMD_NORMAL | B53_SPI_CMD_WRITE; txbuf[1] = reg; put_unaligned_le64(value, &txbuf[2]); return spi_write(spi, txbuf, sizeof(txbuf) - 2); }

Contributors

PersonTokensPropCommitsCommitProp
Florian Fainelli96100.00%1100.00%
Total96100.00%1100.00%


static int b53_spi_write64(struct b53_device *dev, u8 page, u8 reg, u64 value) { struct spi_device *spi = dev->priv; int ret; u8 txbuf[10]; ret = b53_prepare_reg_access(spi, page); if (ret) return ret; txbuf[0] = B53_SPI_CMD_NORMAL | B53_SPI_CMD_WRITE; txbuf[1] = reg; put_unaligned_le64(value, &txbuf[2]); return spi_write(spi, txbuf, sizeof(txbuf)); }

Contributors

PersonTokensPropCommitsCommitProp
Florian Fainelli94100.00%1100.00%
Total94100.00%1100.00%

static const struct b53_io_ops b53_spi_ops = { .read8 = b53_spi_read8, .read16 = b53_spi_read16, .read32 = b53_spi_read32, .read48 = b53_spi_read48, .read64 = b53_spi_read64, .write8 = b53_spi_write8, .write16 = b53_spi_write16, .write32 = b53_spi_write32, .write48 = b53_spi_write48, .write64 = b53_spi_write64, };
static int b53_spi_probe(struct spi_device *spi) { struct b53_device *dev; int ret; dev = b53_switch_alloc(&spi->dev, &b53_spi_ops, spi); if (!dev) return -ENOMEM; if (spi->dev.platform_data) dev->pdata = spi->dev.platform_data; ret = b53_switch_register(dev); if (ret) return ret; spi_set_drvdata(spi, dev); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Florian Fainelli85100.00%1100.00%
Total85100.00%1100.00%


static int b53_spi_remove(struct spi_device *spi) { struct b53_device *dev = spi_get_drvdata(spi); if (dev) b53_switch_remove(dev); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Florian Fainelli33100.00%1100.00%
Total33100.00%1100.00%

static struct spi_driver b53_spi_driver = { .driver = { .name = "b53-switch", }, .probe = b53_spi_probe, .remove = b53_spi_remove, }; module_spi_driver(b53_spi_driver); MODULE_AUTHOR("Jonas Gorski <jogo@openwrt.org>"); MODULE_DESCRIPTION("B53 SPI access driver"); MODULE_LICENSE("Dual BSD/GPL");

Overall Contributors

PersonTokensPropCommitsCommitProp
Florian Fainelli144899.93%150.00%
Julia Lawall10.07%150.00%
Total1449100.00%2100.00%
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
Created with cregit.