linux/arch/arm/mach-sa1100/ssp.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 *  linux/arch/arm/mach-sa1100/ssp.c
   4 *
   5 *  Copyright (C) 2003 Russell King.
   6 *
   7 *  Generic SSP driver.  This provides the generic core for simple
   8 *  IO-based SSP applications.
   9 */
  10#include <linux/module.h>
  11#include <linux/kernel.h>
  12#include <linux/sched.h>
  13#include <linux/errno.h>
  14#include <linux/interrupt.h>
  15#include <linux/ioport.h>
  16#include <linux/init.h>
  17#include <linux/io.h>
  18
  19#include <mach/hardware.h>
  20#include <mach/irqs.h>
  21#include <asm/hardware/ssp.h>
  22
  23#define TIMEOUT 100000
  24
  25static irqreturn_t ssp_interrupt(int irq, void *dev_id)
  26{
  27        unsigned int status = Ser4SSSR;
  28
  29        if (status & SSSR_ROR)
  30                printk(KERN_WARNING "SSP: receiver overrun\n");
  31
  32        Ser4SSSR = SSSR_ROR;
  33
  34        return status ? IRQ_HANDLED : IRQ_NONE;
  35}
  36
  37/**
  38 * ssp_write_word - write a word to the SSP port
  39 * @data: 16-bit, MSB justified data to write.
  40 *
  41 * Wait for a free entry in the SSP transmit FIFO, and write a data
  42 * word to the SSP port.  Wait for the SSP port to start sending
  43 * the data.
  44 *
  45 * The caller is expected to perform the necessary locking.
  46 *
  47 * Returns:
  48 *   %-ETIMEDOUT        timeout occurred
  49 *   0                  success
  50 */
  51int ssp_write_word(u16 data)
  52{
  53        int timeout = TIMEOUT;
  54
  55        while (!(Ser4SSSR & SSSR_TNF)) {
  56                if (!--timeout)
  57                        return -ETIMEDOUT;
  58                cpu_relax();
  59        }
  60
  61        Ser4SSDR = data;
  62
  63        timeout = TIMEOUT;
  64        while (!(Ser4SSSR & SSSR_BSY)) {
  65                if (!--timeout)
  66                        return -ETIMEDOUT;
  67                cpu_relax();
  68        }
  69
  70        return 0;
  71}
  72
  73/**
  74 * ssp_read_word - read a word from the SSP port
  75 *
  76 * Wait for a data word in the SSP receive FIFO, and return the
  77 * received data.  Data is LSB justified.
  78 *
  79 * Note: Currently, if data is not expected to be received, this
  80 * function will wait for ever.
  81 *
  82 * The caller is expected to perform the necessary locking.
  83 *
  84 * Returns:
  85 *   %-ETIMEDOUT        timeout occurred
  86 *   16-bit data        success
  87 */
  88int ssp_read_word(u16 *data)
  89{
  90        int timeout = TIMEOUT;
  91
  92        while (!(Ser4SSSR & SSSR_RNE)) {
  93                if (!--timeout)
  94                        return -ETIMEDOUT;
  95                cpu_relax();
  96        }
  97
  98        *data = (u16)Ser4SSDR;
  99
 100        return 0;
 101}
 102
 103/**
 104 * ssp_flush - flush the transmit and receive FIFOs
 105 *
 106 * Wait for the SSP to idle, and ensure that the receive FIFO
 107 * is empty.
 108 *
 109 * The caller is expected to perform the necessary locking.
 110 *
 111 * Returns:
 112 *   %-ETIMEDOUT        timeout occurred
 113 *   0                  success
 114 */
 115int ssp_flush(void)
 116{
 117        int timeout = TIMEOUT * 2;
 118
 119        do {
 120                while (Ser4SSSR & SSSR_RNE) {
 121                        if (!--timeout)
 122                                return -ETIMEDOUT;
 123                        (void) Ser4SSDR;
 124                }
 125                if (!--timeout)
 126                        return -ETIMEDOUT;
 127        } while (Ser4SSSR & SSSR_BSY);
 128
 129        return 0;
 130}
 131
 132/**
 133 * ssp_enable - enable the SSP port
 134 *
 135 * Turn on the SSP port.
 136 */
 137void ssp_enable(void)
 138{
 139        Ser4SSCR0 |= SSCR0_SSE;
 140}
 141
 142/**
 143 * ssp_disable - shut down the SSP port
 144 *
 145 * Turn off the SSP port, optionally powering it down.
 146 */
 147void ssp_disable(void)
 148{
 149        Ser4SSCR0 &= ~SSCR0_SSE;
 150}
 151
 152/**
 153 * ssp_save_state - save the SSP configuration
 154 * @ssp: pointer to structure to save SSP configuration
 155 *
 156 * Save the configured SSP state for suspend.
 157 */
 158void ssp_save_state(struct ssp_state *ssp)
 159{
 160        ssp->cr0 = Ser4SSCR0;
 161        ssp->cr1 = Ser4SSCR1;
 162
 163        Ser4SSCR0 &= ~SSCR0_SSE;
 164}
 165
 166/**
 167 * ssp_restore_state - restore a previously saved SSP configuration
 168 * @ssp: pointer to configuration saved by ssp_save_state
 169 *
 170 * Restore the SSP configuration saved previously by ssp_save_state.
 171 */
 172void ssp_restore_state(struct ssp_state *ssp)
 173{
 174        Ser4SSSR = SSSR_ROR;
 175
 176        Ser4SSCR0 = ssp->cr0 & ~SSCR0_SSE;
 177        Ser4SSCR1 = ssp->cr1;
 178        Ser4SSCR0 = ssp->cr0;
 179}
 180
 181/**
 182 * ssp_init - setup the SSP port
 183 *
 184 * initialise and claim resources for the SSP port.
 185 *
 186 * Returns:
 187 *   %-ENODEV   if the SSP port is unavailable
 188 *   %-EBUSY    if the resources are already in use
 189 *   %0         on success
 190 */
 191int ssp_init(void)
 192{
 193        int ret;
 194
 195        if (!(PPAR & PPAR_SPR) && (Ser4MCCR0 & MCCR0_MCE))
 196                return -ENODEV;
 197
 198        if (!request_mem_region(__PREG(Ser4SSCR0), 0x18, "SSP")) {
 199                return -EBUSY;
 200        }
 201
 202        Ser4SSSR = SSSR_ROR;
 203
 204        ret = request_irq(IRQ_Ser4SSP, ssp_interrupt, 0, "SSP", NULL);
 205        if (ret)
 206                goto out_region;
 207
 208        return 0;
 209
 210 out_region:
 211        release_mem_region(__PREG(Ser4SSCR0), 0x18);
 212        return ret;
 213}
 214
 215/**
 216 * ssp_exit - undo the effects of ssp_init
 217 *
 218 * release and free resources for the SSP port.
 219 */
 220void ssp_exit(void)
 221{
 222        Ser4SSCR0 &= ~SSCR0_SSE;
 223
 224        free_irq(IRQ_Ser4SSP, NULL);
 225        release_mem_region(__PREG(Ser4SSCR0), 0x18);
 226}
 227
 228MODULE_AUTHOR("Russell King");
 229MODULE_DESCRIPTION("SA11x0 SSP PIO driver");
 230MODULE_LICENSE("GPL");
 231
 232EXPORT_SYMBOL(ssp_write_word);
 233EXPORT_SYMBOL(ssp_read_word);
 234EXPORT_SYMBOL(ssp_flush);
 235EXPORT_SYMBOL(ssp_enable);
 236EXPORT_SYMBOL(ssp_disable);
 237EXPORT_SYMBOL(ssp_save_state);
 238EXPORT_SYMBOL(ssp_restore_state);
 239EXPORT_SYMBOL(ssp_init);
 240EXPORT_SYMBOL(ssp_exit);
 241