コード例 #1
0
ファイル: spi.c プロジェクト: ivucica/linux
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;
}
コード例 #2
0
ファイル: spi.c プロジェクト: ivucica/linux
/*
 * 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;
}
コード例 #3
0
ファイル: spi.c プロジェクト: ivucica/linux
static void spi_drv_shutdown(struct device *dev)
{
	const struct spi_driver		*sdrv = to_spi_driver(dev->driver);

	sdrv->shutdown(to_spi_device(dev));
}
コード例 #4
0
ファイル: spi.c プロジェクト: ivucica/linux
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));
}
コード例 #5
0
ファイル: st7735fb.c プロジェクト: ngreatorex/st7735fb
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;
}
コード例 #6
0
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, &regmap_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),
};
コード例 #7
0
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;
}