diff options
Diffstat (limited to 'drivers/media/video/stradis.c')
-rw-r--r-- | drivers/media/video/stradis.c | 197 |
1 files changed, 113 insertions, 84 deletions
diff --git a/drivers/media/video/stradis.c b/drivers/media/video/stradis.c index 6ee54a45411f..ad6646c7da03 100644 --- a/drivers/media/video/stradis.c +++ b/drivers/media/video/stradis.c | |||
@@ -1991,12 +1991,10 @@ static struct video_device saa_template = | |||
1991 | .minor = -1, | 1991 | .minor = -1, |
1992 | }; | 1992 | }; |
1993 | 1993 | ||
1994 | static int configure_saa7146(struct pci_dev *dev, int num) | 1994 | static int __devinit configure_saa7146(struct pci_dev *pdev, int num) |
1995 | { | 1995 | { |
1996 | int result; | 1996 | int result; |
1997 | struct saa7146 *saa; | 1997 | struct saa7146 *saa = &saa7146s[num]; |
1998 | |||
1999 | saa = &saa7146s[num]; | ||
2000 | 1998 | ||
2001 | saa->endmarkhead = saa->endmarktail = 0; | 1999 | saa->endmarkhead = saa->endmarktail = 0; |
2002 | saa->win.x = saa->win.y = 0; | 2000 | saa->win.x = saa->win.y = 0; |
@@ -2013,7 +2011,6 @@ static int configure_saa7146(struct pci_dev *dev, int num) | |||
2013 | saa->picture.contrast = 38768; | 2011 | saa->picture.contrast = 38768; |
2014 | saa->picture.colour = 32768; | 2012 | saa->picture.colour = 32768; |
2015 | saa->cap = 0; | 2013 | saa->cap = 0; |
2016 | saa->dev = dev; | ||
2017 | saa->nr = num; | 2014 | saa->nr = num; |
2018 | saa->playmode = VID_PLAY_NORMAL; | 2015 | saa->playmode = VID_PLAY_NORMAL; |
2019 | memset(saa->boardcfg, 0, 64); /* clear board config area */ | 2016 | memset(saa->boardcfg, 0, 64); /* clear board config area */ |
@@ -2033,14 +2030,14 @@ static int configure_saa7146(struct pci_dev *dev, int num) | |||
2033 | init_waitqueue_head(&saa->vidq); | 2030 | init_waitqueue_head(&saa->vidq); |
2034 | spin_lock_init(&saa->lock); | 2031 | spin_lock_init(&saa->lock); |
2035 | 2032 | ||
2036 | if (pci_enable_device(dev)) | 2033 | if (pci_enable_device(pdev)) |
2037 | return -EIO; | 2034 | return -EIO; |
2038 | 2035 | ||
2039 | saa->id = dev->device; | 2036 | saa->id = pdev->device; |
2040 | saa->irq = dev->irq; | 2037 | saa->irq = pdev->irq; |
2041 | saa->video_dev.minor = -1; | 2038 | saa->video_dev.minor = -1; |
2042 | saa->saa7146_adr = pci_resource_start(dev, 0); | 2039 | saa->saa7146_adr = pci_resource_start(pdev, 0); |
2043 | pci_read_config_byte(dev, PCI_CLASS_REVISION, &saa->revision); | 2040 | pci_read_config_byte(pdev, PCI_CLASS_REVISION, &saa->revision); |
2044 | 2041 | ||
2045 | saa->saa7146_mem = ioremap(saa->saa7146_adr, 0x200); | 2042 | saa->saa7146_mem = ioremap(saa->saa7146_adr, 0x200); |
2046 | if (!saa->saa7146_mem) | 2043 | if (!saa->saa7146_mem) |
@@ -2051,16 +2048,15 @@ static int configure_saa7146(struct pci_dev *dev, int num) | |||
2051 | result = request_irq(saa->irq, saa7146_irq, | 2048 | result = request_irq(saa->irq, saa7146_irq, |
2052 | SA_SHIRQ | SA_INTERRUPT, "stradis", (void *) saa); | 2049 | SA_SHIRQ | SA_INTERRUPT, "stradis", (void *) saa); |
2053 | if (result == -EINVAL) | 2050 | if (result == -EINVAL) |
2054 | printk(KERN_ERR "stradis%d: Bad irq number or handler\n", | 2051 | dev_err(&pdev->dev, "%d: Bad irq number or handler\n", num); |
2055 | num); | ||
2056 | if (result == -EBUSY) | 2052 | if (result == -EBUSY) |
2057 | printk(KERN_ERR "stradis%d: IRQ %ld busy, change your PnP" | 2053 | dev_err(&pdev->dev, "%d: IRQ %ld busy, change your PnP config " |
2058 | " config in BIOS\n", num, saa->irq); | 2054 | "in BIOS\n", num, saa->irq); |
2059 | if (result < 0) { | 2055 | if (result < 0) { |
2060 | iounmap(saa->saa7146_mem); | 2056 | iounmap(saa->saa7146_mem); |
2061 | return result; | 2057 | return result; |
2062 | } | 2058 | } |
2063 | pci_set_master(dev); | 2059 | pci_set_master(pdev); |
2064 | if (video_register_device(&saa->video_dev, VFL_TYPE_GRABBER, video_nr) < 0) { | 2060 | if (video_register_device(&saa->video_dev, VFL_TYPE_GRABBER, video_nr) < 0) { |
2065 | iounmap(saa->saa7146_mem); | 2061 | iounmap(saa->saa7146_mem); |
2066 | return -1; | 2062 | return -1; |
@@ -2068,10 +2064,11 @@ static int configure_saa7146(struct pci_dev *dev, int num) | |||
2068 | return 0; | 2064 | return 0; |
2069 | } | 2065 | } |
2070 | 2066 | ||
2071 | static int init_saa7146(int i) | 2067 | static int __devinit init_saa7146(int i, struct device *dev) |
2072 | { | 2068 | { |
2073 | struct saa7146 *saa = &saa7146s[i]; | 2069 | struct saa7146 *saa = &saa7146s[i]; |
2074 | 2070 | ||
2071 | memset(saa, 0, sizeof(*saa)); | ||
2075 | saa->user = 0; | 2072 | saa->user = 0; |
2076 | /* reset the saa7146 */ | 2073 | /* reset the saa7146 */ |
2077 | saawrite(0xffff0000, SAA7146_MC1); | 2074 | saawrite(0xffff0000, SAA7146_MC1); |
@@ -2104,7 +2101,7 @@ static int init_saa7146(int i) | |||
2104 | 2101 | ||
2105 | /* allocate 32k dma buffer + 4k for page table */ | 2102 | /* allocate 32k dma buffer + 4k for page table */ |
2106 | if ((saa->dmadebi = kmalloc(32768 + 4096, GFP_KERNEL)) == NULL) { | 2103 | if ((saa->dmadebi = kmalloc(32768 + 4096, GFP_KERNEL)) == NULL) { |
2107 | printk(KERN_ERR "stradis%d: debi kmalloc failed\n", i); | 2104 | dev_err(dev, "%d: debi kmalloc failed\n", i); |
2108 | return -1; | 2105 | return -1; |
2109 | } | 2106 | } |
2110 | #if 0 | 2107 | #if 0 |
@@ -2117,19 +2114,19 @@ static int init_saa7146(int i) | |||
2117 | saa->audtail = saa->vidtail = saa->osdtail = 0; | 2114 | saa->audtail = saa->vidtail = saa->osdtail = 0; |
2118 | if (saa->vidbuf == NULL) | 2115 | if (saa->vidbuf == NULL) |
2119 | if ((saa->vidbuf = vmalloc(524288)) == NULL) { | 2116 | if ((saa->vidbuf = vmalloc(524288)) == NULL) { |
2120 | printk(KERN_ERR "stradis%d: malloc failed\n", saa->nr); | 2117 | dev_err(dev, "%d: malloc failed\n", saa->nr); |
2121 | return -ENOMEM; | 2118 | return -ENOMEM; |
2122 | } | 2119 | } |
2123 | if (saa->audbuf == NULL) | 2120 | if (saa->audbuf == NULL) |
2124 | if ((saa->audbuf = vmalloc(65536)) == NULL) { | 2121 | if ((saa->audbuf = vmalloc(65536)) == NULL) { |
2125 | printk(KERN_ERR "stradis%d: malloc failed\n", saa->nr); | 2122 | dev_err(dev, "%d: malloc failed\n", saa->nr); |
2126 | vfree(saa->vidbuf); | 2123 | vfree(saa->vidbuf); |
2127 | saa->vidbuf = NULL; | 2124 | saa->vidbuf = NULL; |
2128 | return -ENOMEM; | 2125 | return -ENOMEM; |
2129 | } | 2126 | } |
2130 | if (saa->osdbuf == NULL) | 2127 | if (saa->osdbuf == NULL) |
2131 | if ((saa->osdbuf = vmalloc(131072)) == NULL) { | 2128 | if ((saa->osdbuf = vmalloc(131072)) == NULL) { |
2132 | printk(KERN_ERR "stradis%d: malloc failed\n", saa->nr); | 2129 | dev_err(dev, "%d: malloc failed\n", saa->nr); |
2133 | vfree(saa->vidbuf); | 2130 | vfree(saa->vidbuf); |
2134 | vfree(saa->audbuf); | 2131 | vfree(saa->audbuf); |
2135 | saa->vidbuf = saa->audbuf = NULL; | 2132 | saa->vidbuf = saa->audbuf = NULL; |
@@ -2137,7 +2134,7 @@ static int init_saa7146(int i) | |||
2137 | } | 2134 | } |
2138 | /* allocate 81920 byte buffer for clipping */ | 2135 | /* allocate 81920 byte buffer for clipping */ |
2139 | if ((saa->dmavid2 = kmalloc(VIDEO_CLIPMAP_SIZE, GFP_KERNEL)) == NULL) { | 2136 | if ((saa->dmavid2 = kmalloc(VIDEO_CLIPMAP_SIZE, GFP_KERNEL)) == NULL) { |
2140 | printk(KERN_ERR "stradis%d: clip kmalloc failed\n", saa->nr); | 2137 | dev_err(dev, "%d: clip kmalloc failed\n", saa->nr); |
2141 | vfree(saa->vidbuf); | 2138 | vfree(saa->vidbuf); |
2142 | vfree(saa->audbuf); | 2139 | vfree(saa->audbuf); |
2143 | vfree(saa->osdbuf); | 2140 | vfree(saa->osdbuf); |
@@ -2159,89 +2156,121 @@ static int init_saa7146(int i) | |||
2159 | return 0; | 2156 | return 0; |
2160 | } | 2157 | } |
2161 | 2158 | ||
2162 | static void release_saa(void) | 2159 | static void stradis_release_saa(struct pci_dev *pdev) |
2163 | { | 2160 | { |
2164 | u8 command; | 2161 | u8 command; |
2165 | int i; | 2162 | int i = (int)pci_get_drvdata(pdev); |
2166 | struct saa7146 *saa; | 2163 | struct saa7146 *saa = &saa7146s[i]; |
2167 | 2164 | ||
2168 | for (i = 0; i < saa_num; i++) { | 2165 | /* turn off all capturing, DMA and IRQs */ |
2169 | saa = &saa7146s[i]; | 2166 | saawrite(0xffff0000, SAA7146_MC1); /* reset chip */ |
2167 | saawrite(0, SAA7146_MC2); | ||
2168 | saawrite(0, SAA7146_IER); | ||
2169 | saawrite(0xffffffffUL, SAA7146_ISR); | ||
2170 | |||
2171 | /* disable PCI bus-mastering */ | ||
2172 | pci_read_config_byte(pdev, PCI_COMMAND, &command); | ||
2173 | command &= ~PCI_COMMAND_MASTER; | ||
2174 | pci_write_config_byte(pdev, PCI_COMMAND, command); | ||
2175 | |||
2176 | /* unmap and free memory */ | ||
2177 | saa->audhead = saa->audtail = saa->osdhead = 0; | ||
2178 | saa->vidhead = saa->vidtail = saa->osdtail = 0; | ||
2179 | vfree(saa->vidbuf); | ||
2180 | vfree(saa->audbuf); | ||
2181 | vfree(saa->osdbuf); | ||
2182 | kfree(saa->dmavid2); | ||
2183 | saa->audbuf = saa->vidbuf = saa->osdbuf = NULL; | ||
2184 | saa->dmavid2 = NULL; | ||
2185 | kfree(saa->dmadebi); | ||
2186 | kfree(saa->dmavid1); | ||
2187 | kfree(saa->dmavid3); | ||
2188 | kfree(saa->dmaa1in); | ||
2189 | kfree(saa->dmaa1out); | ||
2190 | kfree(saa->dmaa2in); | ||
2191 | kfree(saa->dmaa2out); | ||
2192 | kfree(saa->dmaRPS1); | ||
2193 | kfree(saa->dmaRPS2); | ||
2194 | free_irq(saa->irq, saa); | ||
2195 | if (saa->saa7146_mem) | ||
2196 | iounmap(saa->saa7146_mem); | ||
2197 | if (saa->video_dev.minor != -1) | ||
2198 | video_unregister_device(&saa->video_dev); | ||
2199 | } | ||
2170 | 2200 | ||
2171 | /* turn off all capturing, DMA and IRQs */ | 2201 | static int __devinit stradis_probe(struct pci_dev *pdev, |
2172 | saawrite(0xffff0000, SAA7146_MC1); /* reset chip */ | 2202 | const struct pci_device_id *ent) |
2173 | saawrite(0, SAA7146_MC2); | 2203 | { |
2174 | saawrite(0, SAA7146_IER); | 2204 | int retval = -EINVAL; |
2175 | saawrite(0xffffffffUL, SAA7146_ISR); | ||
2176 | 2205 | ||
2177 | /* disable PCI bus-mastering */ | 2206 | if (saa_num >= SAA7146_MAX) |
2178 | pci_read_config_byte(saa->dev, PCI_COMMAND, &command); | 2207 | goto err; |
2179 | command &= ~PCI_COMMAND_MASTER; | ||
2180 | pci_write_config_byte(saa->dev, PCI_COMMAND, command); | ||
2181 | 2208 | ||
2182 | /* unmap and free memory */ | 2209 | if (!pdev->subsystem_vendor) |
2183 | saa->audhead = saa->audtail = saa->osdhead = 0; | 2210 | dev_info(&pdev->dev, "%d: rev1 decoder\n", saa_num); |
2184 | saa->vidhead = saa->vidtail = saa->osdtail = 0; | 2211 | else |
2185 | vfree(saa->vidbuf); | 2212 | dev_info(&pdev->dev, "%d: SDM2xx found\n", saa_num); |
2186 | vfree(saa->audbuf); | 2213 | |
2187 | vfree(saa->osdbuf); | 2214 | pci_set_drvdata(pdev, (void *)saa_num); |
2188 | kfree(saa->dmavid2); | 2215 | |
2189 | saa->audbuf = saa->vidbuf = saa->osdbuf = NULL; | 2216 | retval = configure_saa7146(pdev, saa_num); |
2190 | saa->dmavid2 = NULL; | 2217 | if (retval) { |
2191 | kfree(saa->dmadebi); | 2218 | dev_err(&pdev->dev, "%d: error in configuring\n", saa_num); |
2192 | kfree(saa->dmavid1); | 2219 | goto err; |
2193 | kfree(saa->dmavid3); | 2220 | } |
2194 | kfree(saa->dmaa1in); | 2221 | |
2195 | kfree(saa->dmaa1out); | 2222 | if (init_saa7146(saa_num, &pdev->dev) < 0) { |
2196 | kfree(saa->dmaa2in); | 2223 | dev_err(&pdev->dev, "%d: error in initialization\n", saa_num); |
2197 | kfree(saa->dmaa2out); | 2224 | retval = -EIO; |
2198 | kfree(saa->dmaRPS1); | 2225 | goto errrel; |
2199 | kfree(saa->dmaRPS2); | ||
2200 | free_irq(saa->irq, saa); | ||
2201 | if (saa->saa7146_mem) | ||
2202 | iounmap(saa->saa7146_mem); | ||
2203 | if (saa->video_dev.minor != -1) | ||
2204 | video_unregister_device(&saa->video_dev); | ||
2205 | } | 2226 | } |
2227 | |||
2228 | saa_num++; | ||
2229 | |||
2230 | return 0; | ||
2231 | errrel: | ||
2232 | stradis_release_saa(pdev); | ||
2233 | err: | ||
2234 | return retval; | ||
2206 | } | 2235 | } |
2207 | 2236 | ||
2237 | static void __devexit stradis_remove(struct pci_dev *pdev) | ||
2238 | { | ||
2239 | stradis_release_saa(pdev); | ||
2240 | } | ||
2241 | |||
2242 | static struct pci_device_id stradis_pci_tbl[] = { | ||
2243 | { PCI_DEVICE(PCI_VENDOR_ID_PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7146) }, | ||
2244 | { 0 } | ||
2245 | }; | ||
2246 | MODULE_DEVICE_TABLE(pci, stradis_pci_tbl); | ||
2247 | |||
2248 | static struct pci_driver stradis_driver = { | ||
2249 | .name = "stradis", | ||
2250 | .id_table = stradis_pci_tbl, | ||
2251 | .probe = stradis_probe, | ||
2252 | .remove = __devexit_p(stradis_remove) | ||
2253 | }; | ||
2208 | 2254 | ||
2209 | static int __init stradis_init (void) | 2255 | int __init stradis_init(void) |
2210 | { | 2256 | { |
2211 | struct pci_dev *dev = NULL; | 2257 | int retval; |
2212 | int result = 0, i; | ||
2213 | 2258 | ||
2214 | saa_num = 0; | 2259 | saa_num = 0; |
2215 | 2260 | ||
2216 | while ((dev = pci_find_device(PCI_VENDOR_ID_PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7146, dev))) { | 2261 | retval = pci_register_driver(&stradis_driver); |
2217 | if (!dev->subsystem_vendor) | 2262 | if (retval) |
2218 | printk(KERN_INFO "stradis%d: rev1 decoder\n", saa_num); | 2263 | printk(KERN_ERR "stradis: Unable to register pci driver.\n"); |
2219 | else | 2264 | |
2220 | printk(KERN_INFO "stradis%d: SDM2xx found\n", saa_num); | 2265 | return retval; |
2221 | result = configure_saa7146(dev, saa_num++); | ||
2222 | if (result) | ||
2223 | return result; | ||
2224 | } | ||
2225 | if (saa_num) | ||
2226 | printk(KERN_INFO "stradis: %d card(s) found.\n", saa_num); | ||
2227 | else | ||
2228 | return -EINVAL; | ||
2229 | for (i = 0; i < saa_num; i++) | ||
2230 | if (init_saa7146(i) < 0) { | ||
2231 | release_saa(); | ||
2232 | return -EIO; | ||
2233 | } | ||
2234 | return 0; | ||
2235 | } | 2266 | } |
2236 | 2267 | ||
2237 | 2268 | ||
2238 | static void __exit stradis_exit (void) | 2269 | void __exit stradis_exit(void) |
2239 | { | 2270 | { |
2240 | release_saa(); | 2271 | pci_unregister_driver(&stradis_driver); |
2241 | printk(KERN_INFO "stradis: module cleanup complete\n"); | 2272 | printk(KERN_INFO "stradis: module cleanup complete\n"); |
2242 | } | 2273 | } |
2243 | 2274 | ||
2244 | |||
2245 | module_init(stradis_init); | 2275 | module_init(stradis_init); |
2246 | module_exit(stradis_exit); | 2276 | module_exit(stradis_exit); |
2247 | |||