From patchwork Tue Feb 9 05:41:50 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitri Belimov X-Patchwork-Id: 77939 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter.kernel.org (8.14.3/8.14.3) with ESMTP id o195fbso010636 for ; Tue, 9 Feb 2010 05:41:37 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751513Ab0BIFlg (ORCPT ); Tue, 9 Feb 2010 00:41:36 -0500 Received: from mail-ew0-f228.google.com ([209.85.219.228]:33738 "EHLO mail-ew0-f228.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750881Ab0BIFle (ORCPT ); Tue, 9 Feb 2010 00:41:34 -0500 Received: by ewy28 with SMTP id 28so3417313ewy.28 for ; Mon, 08 Feb 2010 21:41:32 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:received:received:date:from:to:cc:subject :message-id:in-reply-to:references:x-mailer:mime-version :content-type; bh=aGFOtRISW2vhYml1vmYs/Wu71kIcQwpe7bRY7iNGKMA=; b=aahuBuk8ze4udWCgcB2Q/B/gUzbEVJOsgKhnFGh6xEdTkdKBjBx1zwNuarv5DZhxvN w+f/sQxDtFRwNnNAMufrXfdSY3lJxkqls28z7Xt1XnuwYvBqtMSw6+8wG6wm3s4SHkhu NY1fC0XglOVhOKY/VjG3GZ1OLxzEnf0qIgJc4= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=date:from:to:cc:subject:message-id:in-reply-to:references:x-mailer :mime-version:content-type; b=JB+5w4VZLo8kg8uyUN/J5HmWCW6YoNti0WaHy6rNZKXdcFtLpXIErxRq7EK6PjktJs G3azXAPwFeiQeNjMVrGJvfNESpbSmWnDgc57xIC+LRYdY/dcHECEe4XyH2jAWMdE3qgY m8UWapw/RpDxjJRQaJG3qaBGO5Q1WJiKuJEI4= Received: by 10.213.48.211 with SMTP id s19mr1528873ebf.49.1265694092737; Mon, 08 Feb 2010 21:41:32 -0800 (PST) Received: from glory.loctelecom.ru (ns2.openhardware.ru [84.19.183.172]) by mx.google.com with ESMTPS id 7sm13299829eyg.9.2010.02.08.21.41.28 (version=SSLv3 cipher=RC4-MD5); Mon, 08 Feb 2010 21:41:31 -0800 (PST) Date: Tue, 9 Feb 2010 14:41:50 +0900 From: Dmitri Belimov To: Hans Verkuil Cc: Mauro Carvalho Chehab , linux-media@vger.kernel.org Subject: Re: saa7134 and =?UTF-8?B?w4PCjsOCwrxQRDYxMTUx?= MPEG2 coder Message-ID: <20100209144150.17fafc52@glory.loctelecom.ru> In-Reply-To: <20100129161202.2ecb510a@glory.loctelecom.ru> References: <20091007101142.3b83dbf2@glory.loctelecom.ru> <201001271214.01837.hverkuil@xs4all.nl> <20100128110941.47fda876@glory.loctelecom.ru> <201001281300.25222.hverkuil@xs4all.nl> <20100129161202.2ecb510a@glory.loctelecom.ru> X-Mailer: Claws Mail 3.5.0 (GTK+ 2.16.1; i486-pc-linux-gnu) Mime-Version: 1.0 Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter.kernel.org [140.211.167.41]); Tue, 09 Feb 2010 05:41:38 +0000 (UTC) diff -r b6b82258cf5e linux/drivers/media/video/saa7134/Makefile --- a/linux/drivers/media/video/saa7134/Makefile Thu Dec 31 19:14:54 2009 -0200 +++ b/linux/drivers/media/video/saa7134/Makefile Tue Feb 09 07:38:53 2010 +0900 @@ -1,9 +1,9 @@ saa7134-objs := saa7134-cards.o saa7134-core.o saa7134-i2c.o \ saa7134-ts.o saa7134-tvaudio.o saa7134-vbi.o \ - saa7134-video.o saa7134-input.o + saa7134-video.o saa7134-input.o saa7134-spi.o -obj-$(CONFIG_VIDEO_SAA7134) += saa6752hs.o saa7134.o saa7134-empress.o +obj-$(CONFIG_VIDEO_SAA7134) += saa6752hs.o saa7134.o saa7134-empress.o upd61151.o obj-$(CONFIG_VIDEO_SAA7134_ALSA) += saa7134-alsa.o diff -r b6b82258cf5e linux/drivers/media/video/saa7134/saa7134-cards.c --- a/linux/drivers/media/video/saa7134/saa7134-cards.c Thu Dec 31 19:14:54 2009 -0200 +++ b/linux/drivers/media/video/saa7134/saa7134-cards.c Tue Feb 09 07:38:53 2010 +0900 @@ -4619,6 +4619,7 @@ .name = name_radio, .amux = LINE2, }, + .encoder_type = SAA7134_ENCODER_SAA6752HS, .mpeg = SAA7134_MPEG_EMPRESS, .video_out = CCIR656, .vid_port_opts = (SET_T_CODE_POLARITY_NON_INVERTED | @@ -4656,6 +4657,7 @@ .name = name_radio, .amux = LINE2, }, + .encoder_type = SAA7134_ENCODER_SAA6752HS, .mpeg = SAA7134_MPEG_EMPRESS, .video_out = CCIR656, .vid_port_opts = (SET_T_CODE_POLARITY_NON_INVERTED | @@ -4695,6 +4697,7 @@ .name = name_radio, .amux = LINE2, }, + .encoder_type = SAA7134_ENCODER_SAA6752HS, .mpeg = SAA7134_MPEG_EMPRESS, .video_out = CCIR656, .vid_port_opts = (SET_T_CODE_POLARITY_NON_INVERTED | @@ -5279,23 +5282,51 @@ .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, .mpeg = SAA7134_MPEG_DVB, + .gpiomask = 0x00860000, .inputs = { { .name = name_tv, .vmux = 2, .amux = TV, .tv = 1, - }, { - .name = name_comp1, - .vmux = 0, - .amux = LINE1, + .gpio = 0x00860000 + }, { + .name = name_comp1, + .vmux = 0, + .amux = LINE1, + .gpio = 0x00860000 }, { .name = name_svideo, .vmux = 9, .amux = LINE1, - } }, - .radio = { - .name = name_radio, - .amux = TV, + .gpio = 0x00860000 + } }, + .radio = { + .name = name_radio, + .amux = TV, + .gpio = 0x00860000 + }, + .encoder_type = SAA7134_ENCODER_muPD61151, + .mpeg = SAA7134_MPEG_EMPRESS, + .video_out = CCIR656, + .vid_port_opts = (SET_T_CODE_POLARITY_NON_INVERTED | + SET_CLOCK_NOT_DELAYED | + SET_CLOCK_INVERTED | + SET_VSYNC_OFF), + .spi = { + .cs = 17, + .clock = 18, + .mosi = 23, + .miso = 21, + .num_chipselect = 1, + .spi_enable = 1, + }, + .spi_conf = { + .modalias = "upd61151", + .max_speed_hz = 50000000, + .chip_select = 0, + .mode = SPI_MODE_0, + .controller_data = NULL, + .platform_data = NULL, }, }, [SAA7134_BOARD_ZOLID_HYBRID_PCI] = { diff -r b6b82258cf5e linux/drivers/media/video/saa7134/saa7134-core.c --- a/linux/drivers/media/video/saa7134/saa7134-core.c Thu Dec 31 19:14:54 2009 -0200 +++ b/linux/drivers/media/video/saa7134/saa7134-core.c Tue Feb 09 07:38:53 2010 +0900 @@ -139,6 +139,18 @@ break; } } + +unsigned long saa7134_get_gpio(struct saa7134_dev *dev) +{ + unsigned long status; + + /* rising SAA7134_GPIO_GPRESCAN reads the status */ + saa_andorb(SAA7134_GPIO_GPMODE3,SAA7134_GPIO_GPRESCAN,0); + saa_andorb(SAA7134_GPIO_GPMODE3,SAA7134_GPIO_GPRESCAN,SAA7134_GPIO_GPRESCAN); + status = saa_readl(SAA7134_GPIO_GPSTATUS0 >> 2) & 0xfffffff; + return status; +} + /* ------------------------------------------------------------------ */ @@ -1057,12 +1069,42 @@ saa7134_hwinit2(dev); - /* load i2c helpers */ + /* initialize software SPI bus */ + if (saa7134_boards[dev->board].spi.spi_enable) + { + dev->spi = saa7134_boards[dev->board].spi; + + /* register SPI master and SPI slave */ + if (saa7134_spi_register(dev, &saa7134_boards[dev->board].spi_conf)) + saa7134_boards[dev->board].spi.spi_enable = 0; + } + + /* load bus helpers */ if (card_is_empress(dev)) { - struct v4l2_subdev *sd = - v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap, + struct v4l2_subdev *sd = NULL; + + dev->encoder_type = saa7134_boards[dev->board].encoder_type; + + switch (dev->encoder_type) { + case SAA7134_ENCODER_muPD61151: + { + printk(KERN_INFO "%s: found muPD61151 MPEG encoder\n", dev->name); + + if (saa7134_boards[dev->board].spi.spi_enable) + sd = v4l2_spi_new_subdev(&dev->v4l2_dev, dev->spi_adap, &saa7134_boards[dev->board].spi_conf); + } + break; + case SAA7134_ENCODER_SAA6752HS: + { + sd = v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap, "saa6752hs", "saa6752hs", saa7134_boards[dev->board].empress_addr, NULL); + } + break; + default: + printk(KERN_INFO "%s: MPEG encoder is not configured\n", dev->name); + break; + } if (sd) sd->grp_id = GRP_EMPRESS; @@ -1139,6 +1181,8 @@ return 0; fail4: + if ((card_is_empress(dev)) && (dev->encoder_type == SAA7134_ENCODER_muPD61151)) + saa7134_spi_unregister(dev); saa7134_unregister_video(dev); saa7134_i2c_unregister(dev); free_irq(pci_dev->irq, dev); @@ -1412,6 +1456,7 @@ /* ----------------------------------------------------------- */ EXPORT_SYMBOL(saa7134_set_gpio); +EXPORT_SYMBOL(saa7134_get_gpio); EXPORT_SYMBOL(saa7134_boards); /* ----------------- for the DMA sound modules --------------- */ diff -r b6b82258cf5e linux/drivers/media/video/saa7134/saa7134.h --- a/linux/drivers/media/video/saa7134/saa7134.h Thu Dec 31 19:14:54 2009 -0200 +++ b/linux/drivers/media/video/saa7134/saa7134.h Tue Feb 09 07:38:53 2010 +0900 @@ -30,6 +30,13 @@ #include #include #include + +/* ifdef software SPI insert here start */ +#include +#include +#include +#include +/* ifdef software SPI insert here stop */ #include @@ -337,6 +344,21 @@ SAA7134_MPEG_TS_SERIAL, }; +enum saa7134_encoder_type { + SAA7134_ENCODER_UNUSED, + SAA7134_ENCODER_SAA6752HS, + SAA7134_ENCODER_muPD61151, +}; + +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; +}; + struct saa7134_board { char *name; unsigned int audio_clock; @@ -355,6 +377,10 @@ unsigned char empress_addr; unsigned char rds_addr; + /* SPI info */ + struct saa7134_software_spi spi; + struct spi_board_info spi_conf; + unsigned int tda9887_conf; unsigned int tuner_config; @@ -362,6 +388,7 @@ enum saa7134_video_out video_out; enum saa7134_mpeg_type mpeg; enum saa7134_mpeg_ts_type ts_type; + enum saa7134_encoder_type encoder_type; unsigned int vid_port_opts; unsigned int ts_force_val:1; }; @@ -506,6 +533,12 @@ void (*signal_change)(struct saa7134_dev *dev); }; +struct saa7134_spi_gpio { + struct spi_bitbang bitbang; + struct spi_master *master; + struct saa7134_dev *controller_data; +}; + /* global device status */ struct saa7134_dev { struct list_head devlist; @@ -553,6 +586,10 @@ struct i2c_client i2c_client; unsigned char eedata[256]; int has_rds; + + /* software spi */ + struct saa7134_software_spi spi; + struct spi_master *spi_adap; /* video overlay */ struct v4l2_framebuffer ovbuf; @@ -615,6 +652,7 @@ atomic_t empress_users; struct work_struct empress_workqueue; int empress_started; + enum saa7134_encoder_type encoder_type; #if defined(CONFIG_VIDEO_SAA7134_DVB) || defined(CONFIG_VIDEO_SAA7134_DVB_MODULE) /* SAA7134_MPEG_DVB only */ @@ -681,6 +719,7 @@ void saa7134_track_gpio(struct saa7134_dev *dev, char *msg); void saa7134_set_gpio(struct saa7134_dev *dev, int bit_no, int value); +unsigned long saa7134_get_gpio(struct saa7134_dev *dev); #define SAA7134_PGTABLE_SIZE 4096 @@ -726,6 +765,11 @@ int saa7134_i2c_register(struct saa7134_dev *dev); int saa7134_i2c_unregister(struct saa7134_dev *dev); +/* ----------------------------------------------------------- */ +/* saa7134-spi.c */ + +int saa7134_spi_register(struct saa7134_dev *dev, struct spi_board_info *info); +int saa7134_spi_unregister(struct saa7134_dev *dev); /* ----------------------------------------------------------- */ /* saa7134-video.c */ diff -r b6b82258cf5e linux/drivers/media/video/v4l2-common.c --- a/linux/drivers/media/video/v4l2-common.c Thu Dec 31 19:14:54 2009 -0200 +++ b/linux/drivers/media/video/v4l2-common.c Tue Feb 09 07:38:53 2010 +0900 @@ -51,6 +51,7 @@ #include #include #include +#include #include #include #include @@ -1069,6 +1070,67 @@ #endif /* defined(CONFIG_I2C) */ +//#if defined(CONFIG_SPI) || (defined(CONFIG_SPI_MODULE) && defined(MODULE)) + SPI_BITBANG + +/* Load an spi sub-device. */ + +void v4l2_spi_subdev_init(struct v4l2_subdev *sd, struct spi_device *spi, + const struct v4l2_subdev_ops *ops) +{ + v4l2_subdev_init(sd, ops); + sd->flags |= V4L2_SUBDEV_FL_IS_SPI; + /* the owner is the same as the spi_device's driver owner */ + sd->owner = spi->dev.driver->owner; + /* spi_device and v4l2_subdev point to one another */ + v4l2_set_subdevdata(sd, spi); + spi_set_drvdata(spi, sd); + /* initialize name */ + snprintf(sd->name, sizeof(sd->name), "%s", + spi->dev.driver->name); +} +EXPORT_SYMBOL_GPL(v4l2_spi_subdev_init); + +struct v4l2_subdev *v4l2_spi_new_subdev(struct v4l2_device *v4l2_dev, + struct spi_master *master, struct spi_board_info *info) +{ + struct v4l2_subdev *sd = NULL; + struct spi_device *spi = NULL; + + BUG_ON(!v4l2_dev); + + if (info->modalias) + request_module(info->modalias); + + spi = spi_new_device(master,info); + + if (spi == NULL || spi->dev.driver ==NULL) + goto error; + + if (!try_module_get(spi->dev.driver->owner)) + goto error; + + sd = spi_get_drvdata(spi); + + /* Register with the v4l2_device which increases the module's + use count as well. */ + if (v4l2_device_register_subdev(v4l2_dev, sd)) + sd = NULL; + + /* Decrease the module use count to match the first try_module_get. */ + module_put(spi->dev.driver->owner); + +error: + /* If we have a client but no subdev, then something went wrong and + we must unregister the client. */ + if (spi && sd == NULL) + spi_unregister_device(spi); + + return sd; +} +EXPORT_SYMBOL_GPL(v4l2_spi_new_subdev); + +//#endif /* defined(CONFIG_SPI) */ + /* Clamp x to be between min and max, aligned to a multiple of 2^align. min * and max don't have to be aligned, but there must be at least one valid * value. E.g., min=17,max=31,align=4 is not allowed as there are no multiples diff -r b6b82258cf5e linux/include/media/v4l2-common.h --- a/linux/include/media/v4l2-common.h Thu Dec 31 19:14:54 2009 -0200 +++ b/linux/include/media/v4l2-common.h Tue Feb 09 07:38:53 2010 +0900 @@ -191,6 +191,25 @@ /* ------------------------------------------------------------------------- */ +/* SPI Helper functions */ + +#include + +struct spi_device_id; +struct spi_device; + +/* Load an spi module and return an initialized v4l2_subdev struct. + Only call request_module if module_name != NULL. + The client_type argument is the name of the chip that's on the adapter. */ +struct v4l2_subdev *v4l2_spi_new_subdev(struct v4l2_device *v4l2_dev, + struct spi_master *master, struct spi_board_info *info); + +/* Initialize an v4l2_subdev with data from an spi_device struct */ +void v4l2_spi_subdev_init(struct v4l2_subdev *sd, struct spi_device *spi, + const struct v4l2_subdev_ops *ops); + +/* ------------------------------------------------------------------------- */ + /* Note: these remaining ioctls/structs should be removed as well, but they are still used in tuner-simple.c (TUNER_SET_CONFIG), cx18/ivtv (RESET) and v4l2-int-device.h (v4l2_routing). To remove these ioctls some more cleanup diff -r b6b82258cf5e linux/include/media/v4l2-subdev.h --- a/linux/include/media/v4l2-subdev.h Thu Dec 31 19:14:54 2009 -0200 +++ b/linux/include/media/v4l2-subdev.h Tue Feb 09 07:38:53 2010 +0900 @@ -387,6 +387,8 @@ /* Set this flag if this subdev is a i2c device. */ #define V4L2_SUBDEV_FL_IS_I2C (1U << 0) +/* Set this flag if this subdev is a spi device. */ +#define V4L2_SUBDEV_FL_IS_SPI (1U << 1) /* Each instance of a subdev driver should create this struct, either stand-alone or embedded in a larger struct.