brintos

brintos / linux-shallow public Read only

0
0
Text · 5.9 KiB · e90aa1c Raw
241 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * netup_unidvb_spi.c4 *5 * Internal SPI driver for NetUP Universal Dual DVB-CI6 *7 * Copyright (C) 2014 NetUP Inc.8 * Copyright (C) 2014 Sergey Kozlov <serjk@netup.ru>9 * Copyright (C) 2014 Abylay Ospan <aospan@netup.ru>10 */11 12#include "netup_unidvb.h"13#include <linux/spi/spi.h>14#include <linux/spi/flash.h>15#include <linux/mtd/partitions.h>16#include <mtd/mtd-abi.h>17 18#define NETUP_SPI_CTRL_IRQ	0x100019#define NETUP_SPI_CTRL_IMASK	0x200020#define NETUP_SPI_CTRL_START	0x800021#define NETUP_SPI_CTRL_LAST_CS	0x400022 23#define NETUP_SPI_TIMEOUT	600024 25enum netup_spi_state {26	SPI_STATE_START,27	SPI_STATE_DONE,28};29 30struct netup_spi_regs {31	__u8	data[1024];32	__le16	control_stat;33	__le16	clock_divider;34} __packed __aligned(1);35 36struct netup_spi {37	struct device			*dev;38	struct spi_controller		*ctlr;39	struct netup_spi_regs __iomem	*regs;40	u8 __iomem			*mmio;41	spinlock_t			lock;42	wait_queue_head_t		waitq;43	enum netup_spi_state		state;44};45 46static char netup_spi_name[64] = "fpga";47 48static struct mtd_partition netup_spi_flash_partitions = {49	.name = netup_spi_name,50	.size = 0x1000000, /* 16MB */51	.offset = 0,52	.mask_flags = MTD_CAP_ROM53};54 55static struct flash_platform_data spi_flash_data = {56	.name = "netup0_m25p128",57	.parts = &netup_spi_flash_partitions,58	.nr_parts = 1,59};60 61static struct spi_board_info netup_spi_board = {62	.modalias = "m25p128",63	.max_speed_hz = 11000000,64	.chip_select = 0,65	.mode = SPI_MODE_0,66	.platform_data = &spi_flash_data,67};68 69irqreturn_t netup_spi_interrupt(struct netup_spi *spi)70{71	u16 reg;72	unsigned long flags;73 74	if (!spi)75		return IRQ_NONE;76 77	spin_lock_irqsave(&spi->lock, flags);78	reg = readw(&spi->regs->control_stat);79	if (!(reg & NETUP_SPI_CTRL_IRQ)) {80		spin_unlock_irqrestore(&spi->lock, flags);81		dev_dbg(&spi->ctlr->dev,82			"%s(): not mine interrupt\n", __func__);83		return IRQ_NONE;84	}85	writew(reg | NETUP_SPI_CTRL_IRQ, &spi->regs->control_stat);86	reg = readw(&spi->regs->control_stat);87	writew(reg & ~NETUP_SPI_CTRL_IMASK, &spi->regs->control_stat);88	spi->state = SPI_STATE_DONE;89	wake_up(&spi->waitq);90	spin_unlock_irqrestore(&spi->lock, flags);91	dev_dbg(&spi->ctlr->dev,92		"%s(): SPI interrupt handled\n", __func__);93	return IRQ_HANDLED;94}95 96static int netup_spi_transfer(struct spi_controller *ctlr,97			      struct spi_message *msg)98{99	struct netup_spi *spi = spi_controller_get_devdata(ctlr);100	struct spi_transfer *t;101	int result = 0;102	u32 tr_size;103 104	/* reset CS */105	writew(NETUP_SPI_CTRL_LAST_CS, &spi->regs->control_stat);106	writew(0, &spi->regs->control_stat);107	list_for_each_entry(t, &msg->transfers, transfer_list) {108		tr_size = t->len;109		while (tr_size) {110			u32 frag_offset = t->len - tr_size;111			u32 frag_size = (tr_size > sizeof(spi->regs->data)) ?112					sizeof(spi->regs->data) : tr_size;113			int frag_last = 0;114 115			if (list_is_last(&t->transfer_list,116					&msg->transfers) &&117					frag_offset + frag_size == t->len) {118				frag_last = 1;119			}120			if (t->tx_buf) {121				memcpy_toio(spi->regs->data,122					t->tx_buf + frag_offset,123					frag_size);124			} else {125				memset_io(spi->regs->data,126					0, frag_size);127			}128			spi->state = SPI_STATE_START;129			writew((frag_size & 0x3ff) |130				NETUP_SPI_CTRL_IMASK |131				NETUP_SPI_CTRL_START |132				(frag_last ? NETUP_SPI_CTRL_LAST_CS : 0),133				&spi->regs->control_stat);134			dev_dbg(&spi->ctlr->dev,135				"%s(): control_stat 0x%04x\n",136				__func__, readw(&spi->regs->control_stat));137			wait_event_timeout(spi->waitq,138				spi->state != SPI_STATE_START,139				msecs_to_jiffies(NETUP_SPI_TIMEOUT));140			if (spi->state == SPI_STATE_DONE) {141				if (t->rx_buf) {142					memcpy_fromio(t->rx_buf + frag_offset,143						spi->regs->data, frag_size);144				}145			} else {146				if (spi->state == SPI_STATE_START) {147					dev_dbg(&spi->ctlr->dev,148						"%s(): transfer timeout\n",149						__func__);150				} else {151					dev_dbg(&spi->ctlr->dev,152						"%s(): invalid state %d\n",153						__func__, spi->state);154				}155				result = -EIO;156				goto done;157			}158			tr_size -= frag_size;159			msg->actual_length += frag_size;160		}161	}162done:163	msg->status = result;164	spi_finalize_current_message(ctlr);165	return result;166}167 168static int netup_spi_setup(struct spi_device *spi)169{170	return 0;171}172 173int netup_spi_init(struct netup_unidvb_dev *ndev)174{175	struct spi_controller *ctlr;176	struct netup_spi *nspi;177 178	ctlr = devm_spi_alloc_master(&ndev->pci_dev->dev,179					 sizeof(struct netup_spi));180	if (!ctlr) {181		dev_err(&ndev->pci_dev->dev,182			"%s(): unable to alloc SPI master\n", __func__);183		return -EINVAL;184	}185	nspi = spi_controller_get_devdata(ctlr);186	ctlr->mode_bits = SPI_CPOL | SPI_CPHA | SPI_LSB_FIRST;187	ctlr->bus_num = -1;188	ctlr->num_chipselect = 1;189	ctlr->transfer_one_message = netup_spi_transfer;190	ctlr->setup = netup_spi_setup;191	spin_lock_init(&nspi->lock);192	init_waitqueue_head(&nspi->waitq);193	nspi->ctlr = ctlr;194	nspi->regs = (struct netup_spi_regs __iomem *)(ndev->bmmio0 + 0x4000);195	writew(2, &nspi->regs->clock_divider);196	writew(NETUP_UNIDVB_IRQ_SPI, ndev->bmmio0 + REG_IMASK_SET);197	ndev->spi = nspi;198	if (spi_register_controller(ctlr)) {199		ndev->spi = NULL;200		dev_err(&ndev->pci_dev->dev,201			"%s(): unable to register SPI bus\n", __func__);202		return -EINVAL;203	}204	snprintf(netup_spi_name,205		sizeof(netup_spi_name),206		"fpga_%02x:%02x.%01x",207		ndev->pci_bus,208		ndev->pci_slot,209		ndev->pci_func);210	if (!spi_new_device(ctlr, &netup_spi_board)) {211		spi_unregister_controller(ctlr);212		ndev->spi = NULL;213		dev_err(&ndev->pci_dev->dev,214			"%s(): unable to create SPI device\n", __func__);215		return -EINVAL;216	}217	dev_dbg(&ndev->pci_dev->dev, "%s(): SPI init OK\n", __func__);218	return 0;219}220 221void netup_spi_release(struct netup_unidvb_dev *ndev)222{223	u16 reg;224	unsigned long flags;225	struct netup_spi *spi = ndev->spi;226 227	if (!spi)228		return;229 230	spi_unregister_controller(spi->ctlr);231	spin_lock_irqsave(&spi->lock, flags);232	reg = readw(&spi->regs->control_stat);233	writew(reg | NETUP_SPI_CTRL_IRQ, &spi->regs->control_stat);234	reg = readw(&spi->regs->control_stat);235	writew(reg & ~NETUP_SPI_CTRL_IMASK, &spi->regs->control_stat);236	spin_unlock_irqrestore(&spi->lock, flags);237	ndev->spi = NULL;238}239 240 241