linux-spi.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* SPI bitbang master for TV cards
@ 2009-11-27  5:15 Dmitri Belimov
  0 siblings, 0 replies; 2+ messages in thread
From: Dmitri Belimov @ 2009-11-27  5:15 UTC (permalink / raw)
  To: spi-devel-general-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f

Hi All.

I write some support for our TV cards (open source of course)
One of them has hardware MPEG2 encoder connected to host chip
via GPIO. In our windows drivers we wrote internal simple SPI bitbang
driver. For Linux we want use generic SPI subsystem.
I wrote my ugly code, not working yet.


#include "saa7134-reg.h"
#include "saa7134.h"
#include <media/v4l2-common.h>

/* ----------------------------------------------------------- */

static unsigned int spi_debug;
module_param(spi_debug, int, 0644);
MODULE_PARM_DESC(spi_debug,"enable debug messages [spi]");

#define d1printk if (1 == spi_debug) printk
#define d2printk if (2 == spi_debug) printk

static inline struct saa7134_spi_gpio *to_sb(struct spi_device *spi)
{
	return spi_master_get_devdata(spi->master);
}

static inline void setsck(struct spi_device *dev, int on)
{
	struct saa7134_spi_gpio *sb = to_sb(dev);

	saa7134_set_gpio(sb->controller_data, sb->controller_data->spi.clock, on ? 1 : 0);
}

static inline void setmosi(struct spi_device *dev, int on)
{
	struct saa7134_spi_gpio *sb = to_sb(dev);

	saa7134_set_gpio(sb->controller_data, sb->controller_data->spi.mosi, on ? 1 : 0);
}

static inline u32 getmiso(struct spi_device *dev)
{
	struct saa7134_spi_gpio *sb = to_sb(dev);
	unsigned long status;

	status = saa7134_get_gpio(sb->controller_data);
	if ( status & (1 << sb->controller_data->spi.miso)) return 1;
	else
		return 0;
}

static void saa7134_spi_gpio_chipsel(struct spi_device *dev, int on)
{
	struct saa7134_spi_gpio *sb = to_sb(dev);

	saa7134_set_gpio(sb->controller_data, sb->controller_data->spi.cs, on ? 1 : 0);
}

int saa7134_spi_register(struct saa7134_dev *dev)
{
	struct spi_master *master = dev->spi_adap.master;
	struct saa7134_spi_gpio *sb = &dev->spi_adap;
	int ret = 0;

printk("SPI register start\n");

	if (!dev->spi.spi_enable)
	{
	printk("SPI is not configured\n");
		return 0;
	}

	master = spi_alloc_master(&dev->spi_adap.pdev->dev, sizeof(struct saa7134_spi_gpio));

	if (master == NULL) {
		dev_err(&dev->spi_adap.pdev->dev, "failed to allocate spi master\n");
		ret = -ENOMEM;
		goto err;
	}

	sb = spi_master_get_devdata(master);

	master->num_chipselect = dev->spi.num_chipselect;
	master->bus_num = -1;

	sb->master = spi_master_get(master);

	sb->bitbang.master = sb->master;
	sb->bitbang.master->bus_num = -1;
	sb->bitbang.chipselect = saa7134_spi_gpio_chipsel;
	sb->bitbang.master->num_chipselect = dev->spi.num_chipselect;

	/* set state of spi pins */
	saa7134_set_gpio(dev, dev->spi.cs, 1);
	saa7134_set_gpio(dev, dev->spi.clock, 1);
	saa7134_set_gpio(dev, dev->spi.mosi, 1);
	saa7134_set_gpio(dev, dev->spi.miso, 3);

//	drv_set_drvdata(&sb->master->dev, sb);

	ret = spi_bitbang_start(&sb->bitbang);

	if (ret) {
		dev_err(&dev->spi_adap.pdev->dev, "Failed to register SPI master\n");
		goto err_no_bitbang;
	}

	dev_info(&dev->spi_adap.pdev->dev,
		"spi master registered: bus_num=%d num_chipselect=%d\n",
		master->bus_num, master->num_chipselect);

	sb->controller_data = dev;
printk("SPI register stop and OK\n");
	return 0;

err_no_bitbang:
	spi_master_put(&sb->bitbang.master);
err:
printk("SPI register stop and FAIL\n");
	return ret;
}

int saa7134_spi_unregister(struct saa7134_dev *dev)
{
	spi_bitbang_stop(&dev->spi_adap.bitbang);
	spi_master_put(&dev->spi_adap.bitbang.master);
	return 0;
}


Some structures from saa7134.h

Structure for store config of GPIO
struct saa7134_software_spi {
	unsigned char cs:5;
	unsigned char clock:5;
	unsigned char mosi:5;
	unsigned char miso:5;
	unsigned char num_chipselect:3;
	unsigned char spi_enable:1;
};

Structure for SPI controller
struct saa7134_spi_gpio {
	struct spi_bitbang	bitbang;
	struct spi_master	*master;
	struct platform_device	*pdev;
	struct saa7134_dev	*controller_data;
};

/* global device status */
struct saa7134_dev {

skip

	/* software spi */
	struct saa7134_spi_gpio    spi_adap;
	struct saa7134_software_spi spi;

skip
};

/* ----------------------------------------------------------- */
/* saa7134-spi.c                                               */

int saa7134_spi_register(struct saa7134_dev *dev);
int saa7134_spi_unregister(struct saa7134_dev *dev);

saa7134-spi build to one saa7134 module. When modprobe I get NULL pointer operation.
I don't understand how to write device driver structure for store data about driver.
How to init all structure.
Must sources consist standalon SPI master driver.

With my best regards, Dmitry.

------------------------------------------------------------------------------
Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day 
trial. Simplify your report design, integration and deployment - and focus on 
what you do best, core application coding. Discover what's new with
Crystal Reports now.  http://p.sf.net/sfu/bobj-july

^ permalink raw reply	[flat|nested] 2+ messages in thread
[parent not found: <20091124162250.34ed1be7@glory.loctelecom.ru>]

end of thread, other threads:[~2009-12-02 22:21 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-11-27  5:15 SPI bitbang master for TV cards Dmitri Belimov
     [not found] <20091124162250.34ed1be7@glory.loctelecom.ru>
     [not found] ` <20091124162250.34ed1be7-ToADIhs8vbH6CWgS4j6HTijHesifYMBh@public.gmane.org>
2009-12-02 22:21   ` Grant Likely

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).