static int spi_resume(struct device *dev) { int value; struct spi_driver *drv = to_spi_driver(dev->driver); if (!drv || !drv->resume) return 0; /* resume may restart the i/o queue */ value = drv->resume(to_spi_device(dev)); if (value == 0) dev->power.power_state = PMSG_ON; return value; }
/* * NOTE: the suspend() method for an spi_master controller driver * should verify that all its child devices are marked as suspended; * suspend requests delivered through sysfs power/state files don't * enforce such constraints. */ static int spi_suspend(struct device *dev, pm_message_t message) { int value; struct spi_driver *drv = to_spi_driver(dev->driver); if (!drv || !drv->suspend) return 0; /* suspend will stop irqs and dma; no more i/o */ value = drv->suspend(to_spi_device(dev), message); if (value == 0) dev->power.power_state = message; return value; }
static void spi_drv_shutdown(struct device *dev) { const struct spi_driver *sdrv = to_spi_driver(dev->driver); sdrv->shutdown(to_spi_device(dev)); }
static int spi_drv_remove(struct device *dev) { const struct spi_driver *sdrv = to_spi_driver(dev->driver); return sdrv->remove(to_spi_device(dev)); }
static int __devinit st7735fb_probe (struct spi_device *spi) { int chip = spi_get_device_id(spi)->driver_data; struct st7735fb_platform_data *pdata = spi->dev.platform_data; int vmem_size = WIDTH*HEIGHT*BPP/8; u8 *vmem; struct fb_info *info; struct st7735fb_par *par; int retval = -ENOMEM; if (chip != ST7735_DISPLAY_AF_TFT18) { pr_err("%s: only the %s device is supported\n", DRVNAME, to_spi_driver(spi->dev.driver)->id_table->name); return -EINVAL; } if (!pdata) { pr_err("%s: platform data required for rst and dc info\n", DRVNAME); return -EINVAL; } vmem = vzalloc(vmem_size); if (!vmem) return retval; info = framebuffer_alloc(sizeof(struct st7735fb_par), &spi->dev); if (!info) goto fballoc_fail; info->screen_base = (u8 __force __iomem *)vmem; info->fbops = &st7735fb_ops; info->fix = st7735fb_fix; info->fix.smem_len = vmem_size; info->var = st7735fb_var; /* Choose any packed pixel format as long as it's RGB565 */ info->var.red.offset = 11; info->var.red.length = 5; info->var.green.offset = 5; info->var.green.length = 6; info->var.blue.offset = 0; info->var.blue.length = 5; info->var.transp.offset = 0; info->var.transp.length = 0; info->flags = FBINFO_FLAG_DEFAULT | FBINFO_VIRTFB; info->fbdefio = &st7735fb_defio; fb_deferred_io_init(info); par = info->par; par->info = info; par->spi = spi; par->rst = pdata->rst_gpio; par->dc = pdata->dc_gpio; #ifdef __LITTLE_ENDIAN /* Allocate swapped shadow buffer */ vmem = vzalloc(vmem_size); if (!vmem) return retval; par->ssbuf = vmem; #endif retval = register_framebuffer(info); if (retval < 0) goto fbreg_fail; spi_set_drvdata(spi, info); retval = st7735fb_init_display(par); if (retval < 0) goto init_fail; printk(KERN_INFO "fb%d: %s frame buffer device,\n\tusing %d KiB of video memory\n", info->node, info->fix.id, vmem_size); return 0; /* TODO: release gpios on fail */ init_fail: spi_set_drvdata(spi, NULL); fbreg_fail: framebuffer_release(info); fballoc_fail: vfree(vmem); return retval; }
static int mc13xxx_spi_read(void *context, const void *reg, size_t reg_size, void *val, size_t val_size) { unsigned char w[4] = { *((unsigned char *) reg), 0, 0, 0}; unsigned char r[4]; unsigned char *p = val; struct device *dev = context; struct spi_device *spi = to_spi_device(dev); struct spi_transfer t = { .tx_buf = w, .rx_buf = r, .len = 4, }; struct spi_message m; int ret; if (val_size != 3 || reg_size != 1) return -ENOTSUPP; spi_message_init(&m); spi_message_add_tail(&t, &m); ret = spi_sync(spi, &m); memcpy(p, &r[1], 3); return ret; } static int mc13xxx_spi_write(void *context, const void *data, size_t count) { struct device *dev = context; struct spi_device *spi = to_spi_device(dev); if (count != 4) return -ENOTSUPP; return spi_write(spi, data, count); } /* * We cannot use regmap-spi generic bus implementation here. * The MC13783 chip will get corrupted if CS signal is deasserted * and on i.Mx31 SoC (the target SoC for MC13783 PMIC) the SPI controller * has the following errata (DSPhl22960): * "The CSPI negates SS when the FIFO becomes empty with * SSCTL= 0. Software cannot guarantee that the FIFO will not * drain because of higher priority interrupts and the * non-realtime characteristics of the operating system. As a * result, the SS will negate before all of the data has been * transferred to/from the peripheral." * We workaround this by accessing the SPI controller with a * single transfert. */ static struct regmap_bus regmap_mc13xxx_bus = { .write = mc13xxx_spi_write, .read = mc13xxx_spi_read, }; static int mc13xxx_spi_probe(struct spi_device *spi) { const struct of_device_id *of_id; struct spi_driver *sdrv = to_spi_driver(spi->dev.driver); struct mc13xxx *mc13xxx; struct mc13xxx_platform_data *pdata = dev_get_platdata(&spi->dev); int ret; of_id = of_match_device(mc13xxx_dt_ids, &spi->dev); if (of_id) sdrv->id_table = &mc13xxx_device_id[(enum mc13xxx_id) of_id->data]; mc13xxx = kzalloc(sizeof(*mc13xxx), GFP_KERNEL); if (!mc13xxx) return -ENOMEM; dev_set_drvdata(&spi->dev, mc13xxx); spi->mode = SPI_MODE_0 | SPI_CS_HIGH; mc13xxx->dev = &spi->dev; mutex_init(&mc13xxx->lock); mc13xxx->regmap = regmap_init(&spi->dev, ®map_mc13xxx_bus, &spi->dev, &mc13xxx_regmap_spi_config); if (IS_ERR(mc13xxx->regmap)) { ret = PTR_ERR(mc13xxx->regmap); dev_err(mc13xxx->dev, "Failed to initialize register map: %d\n", ret); dev_set_drvdata(&spi->dev, NULL); kfree(mc13xxx); return ret; } ret = mc13xxx_common_init(mc13xxx, pdata, spi->irq); if (ret) { dev_set_drvdata(&spi->dev, NULL); } else { const struct spi_device_id *devid = spi_get_device_id(spi); if (!devid || devid->driver_data != mc13xxx->ictype) dev_warn(mc13xxx->dev, "device id doesn't match auto detection!\n"); } return ret; } static int __devexit mc13xxx_spi_remove(struct spi_device *spi) { struct mc13xxx *mc13xxx = dev_get_drvdata(&spi->dev); mc13xxx_common_cleanup(mc13xxx); return 0; } static struct spi_driver mc13xxx_spi_driver = { .id_table = mc13xxx_device_id, .driver = { .name = "mc13xxx", .owner = THIS_MODULE, .of_match_table = mc13xxx_dt_ids, }, .probe = mc13xxx_spi_probe, .remove = __devexit_p(mc13xxx_spi_remove), };
static int __devinit st7586fb_probe (struct spi_device *spi) { int chip = spi_get_device_id(spi)->driver_data; struct st7586fb_platform_data *pdata = spi->dev.platform_data; int vmem_size = (WIDTH + 2) / 3 * HEIGHT; u8 *vmem; struct fb_info *info; struct st7586fb_par *par; int retval = -ENOMEM; if (chip != ST7586_DISPLAY_LEGO_EV3) { pr_err("%s: only the %s device is supported\n", DRVNAME, to_spi_driver(spi->dev.driver)->id_table->name); return -EINVAL; } if (!pdata) { pr_err("%s: platform data required for rst and a0 info\n", DRVNAME); return -EINVAL; } vmem = (u8 *)kmalloc(vmem_size, GFP_KERNEL); if (!vmem) return retval; // Zero memory for easy detection if any new data has been written to screenbuffer memset(vmem, 0, vmem_size); info = framebuffer_alloc(sizeof(struct st7586fb_par), &spi->dev); if (!info) goto fballoc_fail; info->screen_base = vmem; info->fbops = &st7586fb_ops; info->fix = st7586fb_fix; info->fix.smem_start = virt_to_phys(vmem); info->fix.smem_len = vmem_size; info->var = st7586fb_var; info->var.red.offset = 0; info->var.red.length = 1; info->var.green.offset = 0; info->var.green.length = 1; info->var.blue.offset = 0; info->var.blue.length = 1; info->var.transp.offset = 0; info->var.transp.length = 0; info->flags = FBINFO_FLAG_DEFAULT | FBINFO_VIRTFB; info->fbdefio = &st7586fb_defio; fb_deferred_io_init(info); par = info->par; par->info = info; par->spi = spi; par->rst = pdata->rst_gpio; par->a0 = pdata->a0_gpio; par->cs = pdata->cs_gpio; par->buf = kmalloc(1, GFP_KERNEL); INIT_DELAYED_WORK(&par->dwork, st7586fb_deferred_work); retval = register_framebuffer(info); if (retval < 0) goto fbreg_fail; spi_set_drvdata(spi, info); retval = st7586fb_request_gpios(par); // Move initing of display to ioctl call to avoid dispaly flickering // as dispaly has already been inited in uboot // retval |= st7586fb_init_display(par); if (retval < 0) goto init_fail; printk(KERN_INFO "fb%d: %s frame buffer device, using %d.%d KiB of video memory\n", info->node, info->fix.id, vmem_size / 1024, vmem_size % 1024 * 10 / 1024); return 0; init_fail: spi_set_drvdata(spi, NULL); fbreg_fail: kfree(par->buf); framebuffer_release(info); fballoc_fail: kfree(vmem); return retval; }