/** * ssp_save_state - save the SSP configuration * @ssp: pointer to structure to save SSP configuration * * Save the configured SSP state for suspend. */ void ssp_save_state(struct ssp_dev *dev, struct ssp_state *ssp) { ssp->cr0 = SSCR0_P(dev->port); ssp->cr1 = SSCR1_P(dev->port); ssp->to = SSTO_P(dev->port); ssp->psp = SSPSP_P(dev->port); SSCR0_P(dev->port) &= ~SSCR0_SSE; }
/** * ssp_restore_state - restore a previously saved SSP configuration * @ssp: pointer to configuration saved by ssp_save_state * * Restore the SSP configuration saved previously by ssp_save_state. */ void ssp_restore_state(struct ssp_dev *dev, struct ssp_state *ssp) { SSSR_P(dev->port) = SSSR_ROR | SSSR_TUR | SSSR_BCE; SSCR0_P(dev->port) = ssp->cr0 & ~SSCR0_SSE; SSCR1_P(dev->port) = ssp->cr1; SSTO_P(dev->port) = ssp->to; SSPSP_P(dev->port) = ssp->psp; SSCR0_P(dev->port) = ssp->cr0; }
/** * ssp_exit - undo the effects of ssp_init * * release and free resources for the SSP port. */ void ssp_exit(struct ssp_dev *dev) { mutex_lock(&mutex); SSCR0_P(dev->port) &= ~SSCR0_SSE; if (dev->port > PXA_SSP_PORTS || dev->port == 0) { printk(KERN_WARNING "SSP: tried to close invalid port\n"); return; } pxa_set_cken(ssp_info[dev->port-1].clock, 0); if (dev->irq) free_irq(dev->irq, dev); release_mem_region(__PREG(SSCR0_P(dev->port)), 0x2c); use_count[dev->port - 1]--; mutex_unlock(&mutex); }
/** * ssp_init - setup the SSP port * * initialise and claim resources for the SSP port. * * Returns: * %-ENODEV if the SSP port is unavailable * %-EBUSY if the resources are already in use * %0 on success */ int ssp_init(struct ssp_dev *dev, u32 port, u32 init_flags) { int ret; if (port > PXA_SSP_PORTS || port == 0) return -ENODEV; mutex_lock(&mutex); if (use_count[port - 1]) { mutex_unlock(&mutex); return -EBUSY; } use_count[port - 1]++; if (!request_mem_region(__PREG(SSCR0_P(port)), 0x2c, "SSP")) { use_count[port - 1]--; mutex_unlock(&mutex); return -EBUSY; } dev->port = port; /* do we need to get irq */ if (!(init_flags & SSP_NO_IRQ)) { ret = request_irq(ssp_info[port-1].irq, ssp_interrupt, 0, "SSP", dev); if (ret) goto out_region; dev->irq = ssp_info[port-1].irq; } else dev->irq = 0; /* turn on SSP port clock */ pxa_set_cken(ssp_info[port-1].clock, 1); mutex_unlock(&mutex); return 0; out_region: release_mem_region(__PREG(SSCR0_P(port)), 0x2c); use_count[port - 1]--; mutex_unlock(&mutex); return ret; }
/** * ssp_config - configure SSP port settings * @mode: port operating mode * @flags: port config flags * @psp_flags: port PSP config flags * @speed: port speed * * Port MUST be disabled by ssp_disable before making any config changes. */ int ssp_config(struct ssp_dev *dev, u32 mode, u32 flags, u32 psp_flags, u32 speed) { dev->mode = mode; dev->flags = flags; dev->psp_flags = psp_flags; dev->speed = speed; /* set up port type, speed, port settings */ SSCR0_P(dev->port) = (dev->speed | dev->mode); SSCR1_P(dev->port) = dev->flags; SSPSP_P(dev->port) = dev->psp_flags; return 0; }
[2] = { .name = "smc91x-attrib", .start = 0x0e000000, .end = 0x0e0fffff, .flags = IORESOURCE_MEM, }, }; /* ADS7846 is connected through SSP ... and if your board has J5 populated, * you can select it to replace the ucb1400 by switching the touchscreen cable * (to J5) and poking board registers (as done below). Else it's only useful * for the temperature sensors. */ static struct resource pxa_ssp_resources[] = { [0] = { .start = __PREG(SSCR0_P(1)), .end = __PREG(SSCR0_P(1)) + 0x14, .flags = IORESOURCE_MEM, }, [1] = { .start = IRQ_SSP, .end = IRQ_SSP, .flags = IORESOURCE_IRQ, }, }; static struct pxa2xx_spi_master pxa_ssp_master_info = { .ssp_type = PXA25x_SSP, .clock_enable = CKEN_SSP, .num_chipselect = 0, };
/** * ssp_disable - shut down the SSP port * * Turn off the SSP port, optionally powering it down. */ void ssp_disable(struct ssp_dev *dev) { SSCR0_P(dev->port) &= ~SSCR0_SSE; }
/** * ssp_enable - enable the SSP port * * Turn on the SSP port. */ void ssp_enable(struct ssp_dev *dev) { SSCR0_P(dev->port) |= SSCR0_SSE; }