static void navpoint_up(struct navpoint *navpoint) { struct ssp_device *ssp = navpoint->ssp; int timeout; clk_prepare_enable(ssp->clk); pxa_ssp_write_reg(ssp, SSCR1, sscr1); pxa_ssp_write_reg(ssp, SSSR, sssr); pxa_ssp_write_reg(ssp, SSTO, 0); pxa_ssp_write_reg(ssp, SSCR0, sscr0); /* SSCR0_SSE written last */ /* Wait until SSP port is ready for slave clock operations */ for (timeout = 100; timeout != 0; --timeout) { if (!(pxa_ssp_read_reg(ssp, SSSR) & SSSR_CSS)) break; msleep(1); } if (timeout == 0) dev_err(navpoint->dev, "timeout waiting for SSSR[CSS] to clear\n"); if (gpio_is_valid(navpoint->gpio)) gpio_set_value(navpoint->gpio, 1); }
static irqreturn_t navpoint_irq(int irq, void *dev_id) { struct navpoint *navpoint = dev_id; struct ssp_device *ssp = navpoint->ssp; irqreturn_t ret = IRQ_NONE; u32 status; status = pxa_ssp_read_reg(ssp, SSSR); if (status & sssr) { dev_warn(navpoint->dev, "unexpected interrupt: status=0x%08x\n", status); pxa_ssp_write_reg(ssp, SSSR, (status & sssr)); ret = IRQ_HANDLED; } while (status & SSSR_RNE) { u32 data; data = pxa_ssp_read_reg(ssp, SSDR); navpoint->data[navpoint->index + 0] = (data >> 8); navpoint->data[navpoint->index + 1] = data; navpoint->index += 2; if (HEADER_LENGTH(navpoint->data[0]) < navpoint->index) { navpoint_packet(navpoint); navpoint->index = 0; } status = pxa_ssp_read_reg(ssp, SSSR); ret = IRQ_HANDLED; } return ret; }
static void navpoint_down(struct navpoint *navpoint) { struct ssp_device *ssp = navpoint->ssp; if (gpio_is_valid(navpoint->gpio)) gpio_set_value(navpoint->gpio, 0); pxa_ssp_write_reg(ssp, SSCR0, 0); clk_disable_unprepare(ssp->clk); }
/** * ssp_set_clkdiv - set SSP clock divider * @div: serial clock rate divider */ static void pxa_ssp_set_scr(struct ssp_device *ssp, u32 div) { u32 sscr0 = pxa_ssp_read_reg(ssp, SSCR0); if (cpu_is_pxa25x() && ssp->type == PXA25x_SSP) { sscr0 &= ~0x0000ff00; sscr0 |= ((div - 2)/2) << 8; /* 2..512 */ } else { sscr0 &= ~0x000fff00; sscr0 |= (div - 1) << 8; /* 1..4096 */ } pxa_ssp_write_reg(ssp, SSCR0, sscr0); }
static struct ssp_device *ssp_lcd_init(void) { struct ssp_device *ssp; ssp = pxa_ssp_request(1, "SSP"); if (ssp == NULL) { printk(KERN_ERR "SSP1 for lcd init failed\n"); return NULL; } clk_enable(ssp->clk); /*disable SSP*/ pxa_ssp_disable(ssp); /* set up port type, speed, port settings */ pxa_ssp_write_reg(ssp, SSCR1, 0x18); pxa_ssp_write_reg(ssp, SSPSP, 0); pxa_ssp_write_reg(ssp, SSCR0, 0x00000588 & (~SSCR0_SSE)); pxa_ssp_enable(ssp); return ssp; }
static int navpoint_probe(struct platform_device *pdev) { const struct navpoint_platform_data *pdata = dev_get_platdata(&pdev->dev); struct ssp_device *ssp; struct input_dev *input; struct navpoint *navpoint; int error; if (!pdata) { dev_err(&pdev->dev, "no platform data\n"); return -EINVAL; } if (gpio_is_valid(pdata->gpio)) { error = gpio_request_one(pdata->gpio, GPIOF_OUT_INIT_LOW, "SYNAPTICS_ON"); if (error) return error; } ssp = pxa_ssp_request(pdata->port, pdev->name); if (!ssp) { error = -ENODEV; goto err_free_gpio; } /* HaRET does not disable devices before jumping into Linux */ if (pxa_ssp_read_reg(ssp, SSCR0) & SSCR0_SSE) { pxa_ssp_write_reg(ssp, SSCR0, 0); dev_warn(&pdev->dev, "ssp%d already enabled\n", pdata->port); } navpoint = kzalloc(sizeof(*navpoint), GFP_KERNEL); input = input_allocate_device(); if (!navpoint || !input) { error = -ENOMEM; goto err_free_mem; } navpoint->ssp = ssp; navpoint->input = input; navpoint->dev = &pdev->dev; navpoint->gpio = pdata->gpio; input->name = pdev->name; input->dev.parent = &pdev->dev; __set_bit(EV_KEY, input->evbit); __set_bit(EV_ABS, input->evbit); __set_bit(BTN_LEFT, input->keybit); __set_bit(BTN_TOUCH, input->keybit); __set_bit(BTN_TOOL_FINGER, input->keybit); input_set_abs_params(input, ABS_X, NAVPOINT_X_MIN, NAVPOINT_X_MAX, 0, 0); input_set_abs_params(input, ABS_Y, NAVPOINT_Y_MIN, NAVPOINT_Y_MAX, 0, 0); input_set_abs_params(input, ABS_PRESSURE, NAVPOINT_PRESSURE_MIN, NAVPOINT_PRESSURE_MAX, 0, 0); input->open = navpoint_open; input->close = navpoint_close; input_set_drvdata(input, navpoint); error = request_irq(ssp->irq, navpoint_irq, 0, pdev->name, navpoint); if (error) goto err_free_mem; error = input_register_device(input); if (error) goto err_free_irq; platform_set_drvdata(pdev, navpoint); dev_dbg(&pdev->dev, "ssp%d, irq %d\n", pdata->port, ssp->irq); return 0; err_free_irq: free_irq(ssp->irq, navpoint); err_free_mem: input_free_device(input); kfree(navpoint); pxa_ssp_free(ssp); err_free_gpio: if (gpio_is_valid(pdata->gpio)) gpio_free(pdata->gpio); return error; }