| /* OMAP SSI internal interface. | |
| * | |
| * Copyright (C) 2010 Nokia Corporation. All rights reserved. | |
| * Copyright (C) 2013 Sebastian Reichel | |
| * | |
| * Contact: Carlos Chinea <carlos.chinea@nokia.com> | |
| * | |
| * 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. | |
| * | |
| * This program is distributed in the hope that it will be useful, but | |
| * WITHOUT ANY WARRANTY; without even the implied warranty of | |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
| * General Public License for more details. | |
| * | |
| * You should have received a copy of the GNU General Public License | |
| * along with this program; if not, write to the Free Software | |
| * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA | |
| * 02110-1301 USA | |
| */ | |
| #ifndef __LINUX_HSI_OMAP_SSI_H__ | |
| #define __LINUX_HSI_OMAP_SSI_H__ | |
| #include <linux/device.h> | |
| #include <linux/module.h> | |
| #include <linux/platform_device.h> | |
| #include <linux/hsi/hsi.h> | |
| #include <linux/gpio/consumer.h> | |
| #include <linux/interrupt.h> | |
| #include <linux/io.h> | |
| #define SSI_MAX_CHANNELS 8 | |
| #define SSI_MAX_GDD_LCH 8 | |
| #define SSI_BYTES_TO_FRAMES(x) ((((x) - 1) >> 2) + 1) | |
| #define SSI_WAKE_EN 0 | |
| /** | |
| * struct omap_ssm_ctx - OMAP synchronous serial module (TX/RX) context | |
| * @mode: Bit transmission mode | |
| * @channels: Number of channels | |
| * @framesize: Frame size in bits | |
| * @timeout: RX frame timeout | |
| * @divisor: TX divider | |
| * @arb_mode: Arbitration mode for TX frame (Round robin, priority) | |
| */ | |
| struct omap_ssm_ctx { | |
| u32 mode; | |
| u32 channels; | |
| u32 frame_size; | |
| union { | |
| u32 timeout; /* Rx Only */ | |
| struct { | |
| u32 arb_mode; | |
| u32 divisor; | |
| }; /* Tx only */ | |
| }; | |
| }; | |
| /** | |
| * struct omap_ssi_port - OMAP SSI port data | |
| * @dev: device associated to the port (HSI port) | |
| * @pdev: platform device associated to the port | |
| * @sst_dma: SSI transmitter physical base address | |
| * @ssr_dma: SSI receiver physical base address | |
| * @sst_base: SSI transmitter base address | |
| * @ssr_base: SSI receiver base address | |
| * @wk_lock: spin lock to serialize access to the wake lines | |
| * @lock: Spin lock to serialize access to the SSI port | |
| * @channels: Current number of channels configured (1,2,4 or 8) | |
| * @txqueue: TX message queues | |
| * @rxqueue: RX message queues | |
| * @brkqueue: Queue of incoming HWBREAK requests (FRAME mode) | |
| * @errqueue: Queue for failed messages | |
| * @errqueue_work: Delayed Work for failed messages | |
| * @irq: IRQ number | |
| * @wake_irq: IRQ number for incoming wake line (-1 if none) | |
| * @wake_gpio: GPIO number for incoming wake line (-1 if none) | |
| * @flags: flags to keep track of states | |
| * @wk_refcount: Reference count for output wake line | |
| * @work: worker for starting TX | |
| * @sys_mpu_enable: Context for the interrupt enable register for irq 0 | |
| * @sst: Context for the synchronous serial transmitter | |
| * @ssr: Context for the synchronous serial receiver | |
| */ | |
| struct omap_ssi_port { | |
| struct device *dev; | |
| struct device *pdev; | |
| dma_addr_t sst_dma; | |
| dma_addr_t ssr_dma; | |
| void __iomem *sst_base; | |
| void __iomem *ssr_base; | |
| spinlock_t wk_lock; | |
| spinlock_t lock; | |
| unsigned int channels; | |
| struct list_head txqueue[SSI_MAX_CHANNELS]; | |
| struct list_head rxqueue[SSI_MAX_CHANNELS]; | |
| struct list_head brkqueue; | |
| struct list_head errqueue; | |
| struct delayed_work errqueue_work; | |
| unsigned int irq; | |
| int wake_irq; | |
| struct gpio_desc *wake_gpio; | |
| bool wktest:1; /* FIXME: HACK to be removed */ | |
| unsigned long flags; | |
| unsigned int wk_refcount; | |
| struct work_struct work; | |
| /* OMAP SSI port context */ | |
| u32 sys_mpu_enable; /* We use only one irq */ | |
| struct omap_ssm_ctx sst; | |
| struct omap_ssm_ctx ssr; | |
| u32 loss_count; | |
| u32 port_id; | |
| #ifdef CONFIG_DEBUG_FS | |
| struct dentry *dir; | |
| #endif | |
| }; | |
| /** | |
| * struct gdd_trn - GDD transaction data | |
| * @msg: Pointer to the HSI message being served | |
| * @sg: Pointer to the current sg entry being served | |
| */ | |
| struct gdd_trn { | |
| struct hsi_msg *msg; | |
| struct scatterlist *sg; | |
| }; | |
| /** | |
| * struct omap_ssi_controller - OMAP SSI controller data | |
| * @dev: device associated to the controller (HSI controller) | |
| * @sys: SSI I/O base address | |
| * @gdd: GDD I/O base address | |
| * @fck: SSI functional clock | |
| * @gdd_irq: IRQ line for GDD | |
| * @gdd_tasklet: bottom half for DMA transfers | |
| * @gdd_trn: Array of GDD transaction data for ongoing GDD transfers | |
| * @lock: lock to serialize access to GDD | |
| * @fck_nb: DVFS notfifier block | |
| * @fck_rate: clock rate | |
| * @loss_count: To follow if we need to restore context or not | |
| * @max_speed: Maximum TX speed (Kb/s) set by the clients. | |
| * @gdd_gcr: SSI GDD saved context | |
| * @get_loss: Pointer to omap_pm_get_dev_context_loss_count, if any | |
| * @port: Array of pointers of the ports of the controller | |
| * @dir: Debugfs SSI root directory | |
| */ | |
| struct omap_ssi_controller { | |
| struct device *dev; | |
| void __iomem *sys; | |
| void __iomem *gdd; | |
| struct clk *fck; | |
| unsigned int gdd_irq; | |
| struct tasklet_struct gdd_tasklet; | |
| struct gdd_trn gdd_trn[SSI_MAX_GDD_LCH]; | |
| spinlock_t lock; | |
| struct notifier_block fck_nb; | |
| unsigned long fck_rate; | |
| u32 loss_count; | |
| u32 max_speed; | |
| /* OMAP SSI Controller context */ | |
| u32 gdd_gcr; | |
| int (*get_loss)(struct device *dev); | |
| struct omap_ssi_port **port; | |
| #ifdef CONFIG_DEBUG_FS | |
| struct dentry *dir; | |
| #endif | |
| }; | |
| void omap_ssi_port_update_fclk(struct hsi_controller *ssi, | |
| struct omap_ssi_port *omap_port); | |
| extern struct platform_driver ssi_port_pdriver; | |
| #endif /* __LINUX_HSI_OMAP_SSI_H__ */ |