static void b2020_configure_tsin(bool freeze)
{
	static struct stm_pad_state *tsin_pad = NULL;

	if (!freeze) {
		tsin_pad = stm_pad_claim(&b20202a_tsin_pad_config, "tsin");
	}
	else {
		if (tsin_pad)
			stm_pad_release(tsin_pad);
		tsin_pad = NULL;
	}
}
Beispiel #2
0
static int __stm_device_init(struct stm_device_state *state,
		struct stm_device_config *config, struct device *dev)
{
	int i;

	state->dev = dev;
	state->config = config;
	state->power_state = stm_device_power_off;

	for (i = 0; i < config->sysconfs_num; i++) {
		struct stm_device_sysconf *sysconf = &config->sysconfs[i];

		state->sysconf_fields[i] = sysconf_claim(sysconf->regtype,
				sysconf->regnum, sysconf->lsb, sysconf->msb,
				dev_name(dev));
		if (!state->sysconf_fields[i])
			goto sysconf_error;
	}

	if (config->init && config->init(state))
		goto sysconf_error;

	if (config->pad_config &&
	    (state->pad_state = stm_pad_claim(config->pad_config,
					      dev_name(dev))) == NULL)
		goto pad_error;

	stm_device_power(state, stm_device_power_on);

	return 0;

pad_error:
	if (config->exit)
		config->exit(state);

sysconf_error:
	for (i--; i>=0; i--)
		sysconf_release(state->sysconf_fields[i]);

	return -EBUSY;
}
static int stxh205_usb_init(struct stm_device_state *device_state)
{
	int result = 0;

	mutex_lock(&stxh205_usb_phy_mutex);

	if (stxh205_usb_phy_count == 0) {
		stxh205_usb_phy_state = stm_pad_claim(
			&stxh205_usb_phy_pad_config, "USBPHY");
		if (!stxh205_usb_phy_state) {
			result = -EBUSY;
			goto err;
		}
	}
	stxh205_usb_phy_count++;

err:
	mutex_unlock(&stxh205_usb_phy_mutex);

	return result;
}
Beispiel #4
0
void __init stx7108_configure_pci(struct stm_plat_pci_config *pci_conf)
{
	struct sysconf_field *sc;
	int i;

	/* LLA clocks have these horrible names... */
	pci_conf->clk_name = "CLKA_PCI";

	/* REQ0 is actually wired to REQ3 to work around NAND problems */
	pci_conf->req0_to_req3 = 1;
	BUG_ON(pci_conf->req_gnt[3] != PCI_PIN_UNUSED);

	/* Fill in the default values */
	if (!pci_conf->ad_override_default) {
		pci_conf->ad_threshold = 5;
		pci_conf->ad_read_ahead = 1;
		pci_conf->ad_chunks_in_msg = 0;
		pci_conf->ad_pcks_in_chunk = 0;
		pci_conf->ad_trigger_mode = 1;
		pci_conf->ad_max_opcode = 5;
		pci_conf->ad_posted = 1;
	}

	/* Copy over platform specific data to driver */
	stx7108_pci_device.dev.platform_data = pci_conf;

#if defined(CONFIG_PM)
#warning TODO: PCI Power Management
#endif
	/* Claim and power up the PCI cell */
	sc = sysconf_claim(SYS_CFG_BANK2, 30, 2, 2, "PCI_PWR_DWN_REQ");
	sysconf_write(sc, 0); /* We will need to stash this somewhere
				 for power management. */
	sc = sysconf_claim(SYS_STA_BANK2, 1, 2, 2, "PCI_PWR_DWN_GRANT");
	while (sysconf_read(sc))
		cpu_relax(); /* Loop until powered up */

	/* Configure the REQ/GNT[1..2], muxed with PIOs */
	for (i = 1; i <= 2; i++) {
		switch (pci_conf->req_gnt[i]) {
		case PCI_PIN_DEFAULT:
			if (stm_pad_claim(&stx7108_pci_reqgnt_pad_config[i],
					"PCI") == NULL) {
				printk(KERN_ERR "Failed to claim REQ/GNT%d "
						"pads!\n", i);
				BUG();
			}
			break;
		case PCI_PIN_UNUSED:
			/* Unused is unused - nothing to do */
			break;
		default:
			/* No alternative here... */
			BUG();
			break;
		}
	}

	/* Configure INTA..D interrupts */
	for (i = 0; i < 4; i++) {
		switch (pci_conf->pci_irq[i]) {
		case PCI_PIN_DEFAULT:
			if (stm_pad_claim(&stx7108_pci_int_pad_config[i],
						"PCI") == NULL) {
				printk(KERN_ERR "Failed to claim INT%c pad!\n",
						'A' + i);
				BUG();
			}
			set_irq_type(ILC_IRQ(122 + i), IRQ_TYPE_LEVEL_LOW);
			break;
		case PCI_PIN_ALTERNATIVE:
			/* There is no alternative here ;-) */
			BUG();
			break;
		default:
			/* Unused or interrupt number passed, nothing to do */
			break;
		}
	}

	/* Configure the SERR interrupt (if wired up) */
	switch (pci_conf->serr_irq) {
	case PCI_PIN_DEFAULT:
		if (gpio_request(STX7108_PIO_PCI_SERR, "PCI_SERR#") == 0) {
			gpio_direction_input(STX7108_PIO_PCI_SERR);
			pci_conf->serr_irq = gpio_to_irq(STX7108_PIO_PCI_SERR);
			set_irq_type(pci_conf->serr_irq, IRQ_TYPE_LEVEL_LOW);
		} else {
			printk(KERN_WARNING "%s(): Failed to claim PCI SERR# "
					"PIO!\n", __func__);
			pci_conf->serr_irq = PCI_PIN_UNUSED;
		}
		break;
	case PCI_PIN_ALTERNATIVE:
		/* No alternative here */
		BUG();
		pci_conf->serr_irq = PCI_PIN_UNUSED;
		break;
	}
	if (pci_conf->serr_irq != PCI_PIN_UNUSED) {
		struct resource *res =
			platform_get_resource_byname(&stx7108_pci_device,
					IORESOURCE_IRQ, "pci serr");

		BUG_ON(!res);
		res->start = pci_conf->serr_irq;
		res->end = pci_conf->serr_irq;
	}

	/* LOCK is not claimed as is totally pointless, the SOCs do not
	 * support any form of coherency */

	stx7108_pci_device.dev.parent =
		bus_find_device_by_name(&platform_bus_type, NULL, "emi");
	platform_device_register(&stx7108_pci_device);
}
Beispiel #5
0
static int __init spi_stm_probe(struct platform_device *pdev)
{
	struct stm_plat_ssc_data *plat_data = pdev->dev.platform_data;
	struct spi_master *master;
	struct resource *res;
	struct spi_stm *spi_stm;
	u32 reg;
	int status = 0;

	master = spi_alloc_master(&pdev->dev, sizeof(struct spi_stm));
	if (!master) {
		dev_err(&pdev->dev, "failed to allocate spi master\n");
		status = -ENOMEM;
		goto err0;
	}

	platform_set_drvdata(pdev, master);

	spi_stm = spi_master_get_devdata(master);
	spi_stm->bitbang.master = spi_master_get(master);
	spi_stm->bitbang.setup_transfer = spi_stm_setup_transfer;
	spi_stm->bitbang.txrx_bufs = spi_stm_txrx_bufs;
	spi_stm->bitbang.master->setup = spi_stm_setup;
	spi_stm->bitbang.master->cleanup = spi_stm_cleanup;

	if (plat_data->spi_chipselect)
		spi_stm->bitbang.chipselect = plat_data->spi_chipselect;
	else
		spi_stm->bitbang.chipselect = spi_stm_gpio_chipselect;

	/* the spi->mode bits understood by this driver: */
	master->mode_bits = MODEBITS;

	/* chip_select field of spi_device is declared as u8 and therefore
	 * limits number of GPIOs that can be used as a CS line. Sorry. */
	master->num_chipselect =
		sizeof(((struct spi_device *)0)->chip_select) * 256;
	master->bus_num = pdev->id;
	init_completion(&spi_stm->done);

	/* Get resources */
	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res) {
		dev_err(&pdev->dev, "failed to find IOMEM resource\n");
		status = -ENOENT;
		goto err1;
	}
	spi_stm->r_mem = *res;

	if (!request_mem_region(res->start,
				res->end - res->start + 1, NAME)) {
		dev_err(&pdev->dev, "request memory region failed [0x%x]\n",
			res->start);
		status = -EBUSY;
		goto err1;
	}

	spi_stm->base = ioremap_nocache(res->start, res->end - res->start + 1);
	if (!spi_stm->base) {
		dev_err(&pdev->dev, "ioremap memory failed [0x%x]\n",
			res->start);
		status = -ENXIO;
		goto err2;
	}

	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
	if (!res) {
		dev_err(&pdev->dev, "failed to find IRQ resource\n");
		status = -ENOENT;
		goto err3;
	}
	spi_stm->r_irq = *res;

	if (request_irq(res->start, spi_stm_irq,
			IRQF_DISABLED, dev_name(&pdev->dev), spi_stm)) {
		dev_err(&pdev->dev, "irq request failed\n");
		status = -EBUSY;
		goto err3;
	}

	spi_stm->pad_state = stm_pad_claim(plat_data->pad_config,
					   dev_name(&pdev->dev));
	if (!spi_stm->pad_state) {
		dev_err(&pdev->dev, "pads request failed\n");
		status = -EBUSY;
		goto err4;
	}

	/* Disable I2C and Reset SSC */
	ssc_store32(spi_stm, SSC_I2C, 0x0);
	reg = ssc_load16(spi_stm, SSC_CTL);
	reg |= SSC_CTL_SR;
	ssc_store32(spi_stm, SSC_CTL, reg);

	udelay(1);
	reg = ssc_load32(spi_stm, SSC_CTL);
	reg &= ~SSC_CTL_SR;
	ssc_store32(spi_stm, SSC_CTL, reg);

	/* Set SSC into slave mode before reconfiguring PIO pins */
	reg = ssc_load32(spi_stm, SSC_CTL);
	reg &= ~SSC_CTL_MS;
	ssc_store32(spi_stm, SSC_CTL, reg);

	spi_stm->clk = clk_get(&pdev->dev, "comms_clk");
	if (!spi_stm->clk) {
		dev_err(&pdev->dev, "Comms clock not found!\n");
		goto err5;
	}

	clk_enable(spi_stm->clk);
	/* Start "bitbang" worker */
	status = spi_bitbang_start(&spi_stm->bitbang);
	if (status) {
		dev_err(&pdev->dev, "bitbang start failed [%d]\n", status);
		goto err5;
	}

	dev_info(&pdev->dev, "registered SPI Bus %d\n", master->bus_num);

	return status;

 err5:
	stm_pad_release(spi_stm->pad_state);
 err4:
	free_irq(spi_stm->r_irq.start, spi_stm);
 err3:
	iounmap(spi_stm->base);
 err2:
	release_mem_region(spi_stm->r_mem.start,
			   resource_size(&spi_stm->r_mem));
 err1:
	spi_master_put(spi_stm->bitbang.master);
	platform_set_drvdata(pdev, NULL);
 err0:
	return status;
}
Beispiel #6
0
static int snd_stm_pcm_player_probe(struct platform_device *pdev)
{
	int result = 0;
	struct snd_stm_pcm_player *pcm_player;
	struct snd_card *card = snd_stm_card_get();
	int i;

	snd_stm_printd(0, "%s('%s')\n", __func__, dev_name(&pdev->dev));

	BUG_ON(!card);

	pcm_player = kzalloc(sizeof(*pcm_player), GFP_KERNEL);
	if (!pcm_player) {
		snd_stm_printe("Can't allocate memory "
				"for a device description!\n");
		result = -ENOMEM;
		goto error_alloc;
	}
	snd_stm_magic_set(pcm_player);
	pcm_player->info = pdev->dev.platform_data;
	BUG_ON(!pcm_player->info);
	pcm_player->ver = pcm_player->info->ver;
	BUG_ON(pcm_player->ver <= 0);
	pcm_player->device = &pdev->dev;

	/* Get resources */

	result = snd_stm_memory_request(pdev, &pcm_player->mem_region,
			&pcm_player->base);
	if (result < 0) {
		snd_stm_printe("Memory region request failed!\n");
		goto error_memory_request;
	}
	pcm_player->fifo_phys_address = pcm_player->mem_region->start +
		offset__AUD_PCMOUT_DATA(pcm_player);
	snd_stm_printd(0, "FIFO physical address: 0x%lx.\n",
			pcm_player->fifo_phys_address);

	result = snd_stm_irq_request(pdev, &pcm_player->irq,
			snd_stm_pcm_player_irq_handler, pcm_player);
	if (result < 0) {
		snd_stm_printe("IRQ request failed!\n");
		goto error_irq_request;
	}

	result = snd_stm_fdma_request(pdev, &pcm_player->fdma_channel);
	if (result < 0) {
		snd_stm_printe("FDMA request failed!\n");
		goto error_fdma_request;
	}

	/* FDMA transfer size depends (among others ;-) on FIFO length,
	 * which is:
	 * - 30 cells (120 bytes) in STx7100/9 and STx7200 cut 1.0
	 * - 70 cells (280 bytes) in STx7111 and STx7200 cut 2.0. */

	if (pcm_player->ver < 5)
		pcm_player->fdma_max_transfer_size = 2;
	else if (pcm_player->ver == 5)
		pcm_player->fdma_max_transfer_size = 20;
	else
		pcm_player->fdma_max_transfer_size = 30;

	/* Get player capabilities */

	snd_stm_printd(0, "Player's name is '%s'\n", pcm_player->info->name);

	BUG_ON(pcm_player->info->channels <= 0);
	BUG_ON(pcm_player->info->channels > 10);
	BUG_ON(pcm_player->info->channels % 2 != 0);
	if (pcm_player->ver > 1) {
		static unsigned int channels_2_10[] = { 2, 4, 6, 8, 10 };

		pcm_player->channels_constraint.list = channels_2_10;
		pcm_player->channels_constraint.count =
			pcm_player->info->channels / 2;
	} else {
		/* In STx7100 cut < 3.0 PCM player ignored NUM_CH setting in
		 * AUD_PCMOUT_FMT register (and it was always in 10 channels
		 * mode...) */
		static unsigned int channels_10[] = { 10 };

		pcm_player->channels_constraint.list = channels_10;
		pcm_player->channels_constraint.count = 1;
	}
	pcm_player->channels_constraint.mask = 0;
	for (i = 0; i < pcm_player->channels_constraint.count; i++)
		snd_stm_printd(0, "Player capable of playing %u-channels PCM."
				"\n", pcm_player->channels_constraint.list[i]);

	/* STx7100 has a problem with 16/16 bits FIFO organization,
	 * so we disable the 16 bits samples capability... */
	if (pcm_player->ver <= 2)
		snd_stm_pcm_player_hw.formats &= ~SNDRV_PCM_FMTBIT_S16_LE;

	/* Create ALSA lowlevel device */

	result = snd_device_new(card, SNDRV_DEV_LOWLEVEL, pcm_player,
			&snd_stm_pcm_player_snd_device_ops);
	if (result < 0) {
		snd_stm_printe("ALSA low level device creation failed!\n");
		goto error_device;
	}

	/* Create ALSA PCM device */

	result = snd_pcm_new(card, NULL, pcm_player->info->card_device, 1, 0,
			&pcm_player->pcm);
	if (result < 0) {
		snd_stm_printe("ALSA PCM instance creation failed!\n");
		goto error_pcm;
	}
	pcm_player->pcm->private_data = pcm_player;
	strcpy(pcm_player->pcm->name, pcm_player->info->name);

	snd_pcm_set_ops(pcm_player->pcm, SNDRV_PCM_STREAM_PLAYBACK,
			&snd_stm_pcm_player_pcm_ops);

	/* Initialize buffer */

	pcm_player->buffer = snd_stm_buffer_create(pcm_player->pcm,
			pcm_player->device,
			snd_stm_pcm_player_hw.buffer_bytes_max);
	if (!pcm_player->buffer) {
		snd_stm_printe("Cannot initialize buffer!\n");
		result = -ENOMEM;
		goto error_buffer_init;
	}

	/* Register in converters router */

	pcm_player->conv_source = snd_stm_conv_register_source(
		&platform_bus_type, dev_name(&pdev->dev),
			pcm_player->info->channels,
			card, pcm_player->info->card_device);
	if (!pcm_player->conv_source) {
		snd_stm_printe("Cannot register in converters router!\n");
		result = -ENOMEM;
		goto error_conv_register_source;
	}

	/* Claim the pads */

	if (pcm_player->info->pad_config) {
		pcm_player->pads = stm_pad_claim(pcm_player->info->pad_config,
				dev_name(&pdev->dev));
		if (!pcm_player->pads) {
			snd_stm_printe("Failed to claimed pads for '%s'!\n",
					dev_name(&pdev->dev));
			result = -EBUSY;
			goto error_pad_claim;
		}
	}

	/* Done now */

	platform_set_drvdata(pdev, pcm_player);

	return 0;

error_pad_claim:
	snd_stm_conv_unregister_source(pcm_player->conv_source);
error_conv_register_source:
	snd_stm_buffer_dispose(pcm_player->buffer);
error_buffer_init:
	/* snd_pcm_free() is not available - PCM device will be released
	 * during card release */
error_pcm:
	snd_device_free(card, pcm_player);
error_device:
	snd_stm_fdma_release(pcm_player->fdma_channel);
error_fdma_request:
	snd_stm_irq_release(pcm_player->irq, pcm_player);
error_irq_request:
	snd_stm_memory_release(pcm_player->mem_region, pcm_player->base);
error_memory_request:
	snd_stm_magic_clear(pcm_player);
	kfree(pcm_player);
error_alloc:
	return result;
}