From 88523a61558a040546bf7d8b079ae0755d8e7005 Mon Sep 17 00:00:00 2001 From: Sam Bradshaw Date: Tue, 30 Aug 2011 08:34:26 -0600 Subject: block: Add driver for Micron RealSSD pcie flash cards This adds mtip32xx, a driver supporting Microns line of pci-express flash storage cards. Signed-off-by: Asai Thambi S P Signed-off-by: Sam Bradshaw Signed-off-by: Jens Axboe diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig index 6f07ec1..a30aa10 100644 --- a/drivers/block/Kconfig +++ b/drivers/block/Kconfig @@ -116,6 +116,8 @@ config PARIDE source "drivers/block/paride/Kconfig" +source "drivers/block/mtip32xx/Kconfig" + config BLK_CPQ_DA tristate "Compaq SMART2 support" depends on PCI && VIRT_TO_BUS diff --git a/drivers/block/Makefile b/drivers/block/Makefile index 76646e9..ad7b74a 100644 --- a/drivers/block/Makefile +++ b/drivers/block/Makefile @@ -39,5 +39,6 @@ obj-$(CONFIG_XEN_BLKDEV_FRONTEND) += xen-blkfront.o obj-$(CONFIG_XEN_BLKDEV_BACKEND) += xen-blkback/ obj-$(CONFIG_BLK_DEV_DRBD) += drbd/ obj-$(CONFIG_BLK_DEV_RBD) += rbd.o +obj-$(CONFIG_BLK_DEV_PCIESSD_MTIP32XX) += mtip32xx/ swim_mod-y := swim.o swim_asm.o diff --git a/drivers/block/mtip32xx/Kconfig b/drivers/block/mtip32xx/Kconfig new file mode 100644 index 0000000..b5dd14e --- /dev/null +++ b/drivers/block/mtip32xx/Kconfig @@ -0,0 +1,9 @@ +# +# mtip32xx device driver configuration +# + +config BLK_DEV_PCIESSD_MTIP32XX + tristate "Block Device Driver for Micron PCIe SSDs" + depends on HOTPLUG_PCI_PCIE + help + This enables the block driver for Micron PCIe SSDs. diff --git a/drivers/block/mtip32xx/Makefile b/drivers/block/mtip32xx/Makefile new file mode 100644 index 0000000..4fbef8c --- /dev/null +++ b/drivers/block/mtip32xx/Makefile @@ -0,0 +1,5 @@ +# +# Makefile for Block device driver for Micron PCIe SSD +# + +obj-$(CONFIG_BLK_DEV_PCIESSD_MTIP32XX) += mtip32xx.o diff --git a/drivers/block/mtip32xx/mtip32xx.c b/drivers/block/mtip32xx/mtip32xx.c new file mode 100644 index 0000000..847b8ff --- /dev/null +++ b/drivers/block/mtip32xx/mtip32xx.c @@ -0,0 +1,3581 @@ +/* + * Driver for the Micron P320 SSD + * Copyright (C) 2011 Micron Technology, Inc. + * + * Portions of this code were derived from works subjected to the + * following copyright: + * Copyright (C) 2009 Integrated Device Technology, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include <../drivers/ata/ahci.h> +#include "mtip32xx.h" + +#define HW_CMD_SLOT_SZ (MTIP_MAX_COMMAND_SLOTS * 32) +#define HW_CMD_TBL_SZ (AHCI_CMD_TBL_HDR_SZ + (MTIP_MAX_SG * 16)) +#define HW_CMD_TBL_AR_SZ (HW_CMD_TBL_SZ * MTIP_MAX_COMMAND_SLOTS) +#define HW_PORT_PRIV_DMA_SZ \ + (HW_CMD_SLOT_SZ + HW_CMD_TBL_AR_SZ + AHCI_RX_FIS_SZ) + +#define HOST_HSORG 0xFC +#define HSORG_DISABLE_SLOTGRP_INTR (1<<24) +#define HSORG_DISABLE_SLOTGRP_PXIS (1<<16) +#define HSORG_HWREV 0xFF00 +#define HSORG_STYLE 0x8 +#define HSORG_SLOTGROUPS 0x7 + +#define PORT_COMMAND_ISSUE 0x38 +#define PORT_SDBV 0x7C + +#define PORT_OFFSET 0x100 +#define PORT_MEM_SIZE 0x80 + +#define PORT_IRQ_ERR \ + (PORT_IRQ_HBUS_ERR | PORT_IRQ_IF_ERR | PORT_IRQ_CONNECT | \ + PORT_IRQ_PHYRDY | PORT_IRQ_UNK_FIS | PORT_IRQ_BAD_PMP | \ + PORT_IRQ_TF_ERR | PORT_IRQ_HBUS_DATA_ERR | PORT_IRQ_IF_NONFATAL | \ + PORT_IRQ_OVERFLOW) +#define PORT_IRQ_LEGACY \ + (PORT_IRQ_PIOS_FIS | PORT_IRQ_D2H_REG_FIS) +#define PORT_IRQ_HANDLED \ + (PORT_IRQ_SDB_FIS | PORT_IRQ_LEGACY | \ + PORT_IRQ_TF_ERR | PORT_IRQ_IF_ERR | \ + PORT_IRQ_CONNECT | PORT_IRQ_PHYRDY) +#define DEF_PORT_IRQ \ + (PORT_IRQ_ERR | PORT_IRQ_LEGACY | PORT_IRQ_SDB_FIS) + +/* product numbers */ +#define MTIP_PRODUCT_UNKNOWN 0x00 +#define MTIP_PRODUCT_ASICFPGA 0x11 + +/* Device instance number, incremented each time a device is probed. */ +static int instance; + +/* + * Global variable used to hold the major block device number + * allocated in mtip_init(). + */ +int mtip_major; + +static DEFINE_SPINLOCK(rssd_index_lock); +static DEFINE_IDA(rssd_index_ida); + +struct mtip_compat_ide_task_request_s { + __u8 io_ports[8]; + __u8 hob_ports[8]; + ide_reg_valid_t out_flags; + ide_reg_valid_t in_flags; + int data_phase; + int req_cmd; + compat_ulong_t out_size; + compat_ulong_t in_size; +}; + +static int mtip_exec_internal_command(struct mtip_port *port, + void *fis, + int fisLen, + dma_addr_t buffer, + int bufLen, + u32 opts, + gfp_t atomic, + unsigned long timeout); + +/* + * Obtain an empty command slot. + * + * This function needs to be reentrant since it could be called + * at the same time on multiple CPUs. The allocation of the + * command slot must be atomic. + * + * @port Pointer to the port data structure. + * + * return value + * >= 0 Index of command slot obtained. + * -1 No command slots available. + */ +static int get_slot(struct mtip_port *port) +{ + int slot, i; + unsigned int num_command_slots = port->dd->slot_groups * 32; + + /* + * Try 10 times, because there is a small race here. + * that's ok, because it's still cheaper than a lock. + * + * Race: Since this section is not protected by lock, same bit + * could be chosen by different process contexts running in + * different processor. So instead of costly lock, we are going + * with loop. + */ + for (i = 0; i < 10; i++) { + slot = find_next_zero_bit(port->allocated, + num_command_slots, 1); + if ((slot < num_command_slots) && + (!test_and_set_bit(slot, port->allocated))) + return slot; + } + dev_warn(&port->dd->pdev->dev, "Failed to get a tag.\n"); + + if (mtip_check_surprise_removal(port->dd->pdev)) { + /* Device not present, clean outstanding commands */ + mtip_command_cleanup(port->dd); + } + return -1; +} + +/* + * Release a command slot. + * + * @port Pointer to the port data structure. + * @tag Tag of command to release + * + * return value + * None + */ +static inline void release_slot(struct mtip_port *port, int tag) +{ + smp_mb__before_clear_bit(); + clear_bit(tag, port->allocated); + smp_mb__after_clear_bit(); +} + +/* + * Issue a command to the hardware. + * + * Set the appropriate bit in the s_active and Command Issue hardware + * registers, causing hardware command processing to begin. + * + * @port Pointer to the port structure. + * @tag The tag of the command to be issued. + * + * return value + * None + */ +static inline void mtip_issue_ncq_command(struct mtip_port *port, int tag) +{ + unsigned long flags = 0; + + atomic_set(&port->commands[tag].active, 1); + + spin_lock_irqsave(&port->cmd_issue_lock, flags); + + writel((1 << MTIP_TAG_BIT(tag)), + port->s_active[MTIP_TAG_INDEX(tag)]); + writel((1 << MTIP_TAG_BIT(tag)), + port->cmd_issue[MTIP_TAG_INDEX(tag)]); + + spin_unlock_irqrestore(&port->cmd_issue_lock, flags); +} + +/* + * Called periodically to see if any read/write commands are + * taking too long to complete. + * + * @data Pointer to the PORT data structure. + * + * return value + * None + */ +void mtip_timeout_function(unsigned long int data) +{ + struct mtip_port *port = (struct mtip_port *) data; + struct host_to_dev_fis *fis; + struct mtip_cmd *command; + int tag, cmdto_cnt = 0; + unsigned int bit, group; + unsigned int num_command_slots = port->dd->slot_groups * 32; + + if (unlikely(!port)) + return; + + if (atomic_read(&port->dd->resumeflag) == true) { + mod_timer(&port->cmd_timer, + jiffies + msecs_to_jiffies(30000)); + return; + } + + for (tag = 0; tag < num_command_slots; tag++) { + /* + * Skip internal command slot as it has + * its own timeout mechanism + */ + if (tag == MTIP_TAG_INTERNAL) + continue; + + if (atomic_read(&port->commands[tag].active) && + (time_after(jiffies, port->commands[tag].comp_time))) { + group = tag >> 5; + bit = tag & 0x1f; + + command = &port->commands[tag]; + fis = (struct host_to_dev_fis *) command->command; + + dev_warn(&port->dd->pdev->dev, + "Timeout for command tag %d\n", tag); + + cmdto_cnt++; + if (cmdto_cnt == 1) + atomic_inc(&port->dd->eh_active); + + /* + * Clear the completed bit. This should prevent + * any interrupt handlers from trying to retire + * the command. + */ + writel(1 << bit, port->completed[group]); + + /* Call the async completion callback. */ + if (likely(command->async_callback)) + command->async_callback(command->async_data, + -EIO); + command->async_callback = NULL; + command->comp_func = NULL; + + /* Unmap the DMA scatter list entries */ + dma_unmap_sg(&port->dd->pdev->dev, + command->sg, + command->scatter_ents, + command->direction); + + /* + * Clear the allocated bit and active tag for the + * command. + */ + atomic_set(&port->commands[tag].active, 0); + release_slot(port, tag); + + up(&port->cmd_slot); + } + } + + if (cmdto_cnt) { + dev_warn(&port->dd->pdev->dev, + "%d commands timed out: restarting port", + cmdto_cnt); + mtip_restart_port(port); + atomic_dec(&port->dd->eh_active); + } + + /* Restart the timer */ + mod_timer(&port->cmd_timer, + jiffies + msecs_to_jiffies(MTIP_TIMEOUT_CHECK_PERIOD)); +} + +/* + * IO completion function. + * + * This completion function is called by the driver ISR when a + * command that was issued by the kernel completes. It first calls the + * asynchronous completion function which normally calls back into the block + * layer passing the asynchronous callback data, then unmaps the + * scatter list associated with the completed command, and finally + * clears the allocated bit associated with the completed command. + * + * @port Pointer to the port data structure. + * @tag Tag of the command. + * @data Pointer to driver_data. + * @status Completion status. + * + * return value + * None + */ +static void mtip_async_complete(struct mtip_port *port, + int tag, + void *data, + int status) +{ + struct mtip_cmd *command; + struct driver_data *dd = data; + int cb_status = status ? -EIO : 0; + + if (unlikely(!dd) || unlikely(!port)) + return; + + command = &port->commands[tag]; + + if (unlikely(status == PORT_IRQ_TF_ERR)) { + dev_warn(&port->dd->pdev->dev, + "Command tag %d failed due to TFE\n", tag); + } + + /* Upper layer callback */ + if (likely(command->async_callback)) + command->async_callback(command->async_data, cb_status); + + command->async_callback = NULL; + command->comp_func = NULL; + + /* Unmap the DMA scatter list entries */ + dma_unmap_sg(&dd->pdev->dev, + command->sg, + command->scatter_ents, + command->direction); + + /* Clear the allocated and active bits for the command */ + atomic_set(&port->commands[tag].active, 0); + release_slot(port, tag); + + up(&port->cmd_slot); +} + +/* + * Internal command completion callback function. + * + * This function is normally called by the driver ISR when an internal + * command completed. This function signals the command completion by + * calling complete(). + * + * @port Pointer to the port data structure. + * @tag Tag of the command that has completed. + * @data Pointer to a completion structure. + * @status Completion status. + * + * return value + * None + */ +static void mtip_completion(struct mtip_port *port, + int tag, + void *data, + int status) +{ + struct mtip_cmd *command = &port->commands[tag]; + struct completion *waiting = data; + if (unlikely(status == PORT_IRQ_TF_ERR)) + dev_warn(&port->dd->pdev->dev, + "Internal command %d completed with TFE\n", tag); + + command->async_callback = NULL; + command->comp_func = NULL; + + complete(waiting); +} + +/* + * Enable/disable the reception of FIS + * + * @port Pointer to the port data structure + * @enable 1 to enable, 0 to disable + * + * return value + * Previous state: 1 enabled, 0 disabled + */ +static int mtip_enable_fis(struct mtip_port *port, int enable) +{ + u32 tmp; + + /* enable FIS reception */ + tmp = readl(port->mmio + PORT_CMD); + if (enable) + writel(tmp | PORT_CMD_FIS_RX, port->mmio + PORT_CMD); + else + writel(tmp & ~PORT_CMD_FIS_RX, port->mmio + PORT_CMD); + + /* Flush */ + readl(port->mmio + PORT_CMD); + + return (((tmp & PORT_CMD_FIS_RX) == PORT_CMD_FIS_RX)); +} + +/* + * Enable/disable the DMA engine + * + * @port Pointer to the port data structure + * @enable 1 to enable, 0 to disable + * + * return value + * Previous state: 1 enabled, 0 disabled. + */ +static int mtip_enable_engine(struct mtip_port *port, int enable) +{ + u32 tmp; + + /* enable FIS reception */ + tmp = readl(port->mmio + PORT_CMD); + if (enable) + writel(tmp | PORT_CMD_START, port->mmio + PORT_CMD); + else + writel(tmp & ~PORT_CMD_START, port->mmio + PORT_CMD); + + readl(port->mmio + PORT_CMD); + return (((tmp & PORT_CMD_START) == PORT_CMD_START)); +} + +/* + * Enables the port DMA engine and FIS reception. + * + * return value + * None + */ +static inline void mtip_start_port(struct mtip_port *port) +{ + /* Enable FIS reception */ + mtip_enable_fis(port, 1); + + /* Enable the DMA engine */ + mtip_enable_engine(port, 1); +} + +/* + * Deinitialize a port by disabling port interrupts, the DMA engine, + * and FIS reception. + * + * @port Pointer to the port structure + * + * return value + * None + */ +static inline void mtip_deinit_port(struct mtip_port *port) +{ + /* Disable interrupts on this port */ + writel(0, port->mmio + PORT_IRQ_MASK); + + /* Disable the DMA engine */ + mtip_enable_engine(port, 0); + + /* Disable FIS reception */ + mtip_enable_fis(port, 0); +} + +/* + * Initialize a port. + * + * This function deinitializes the port by calling mtip_deinit_port() and + * then initializes it by setting the command header and RX FIS addresses, + * clearing the SError register and any pending port interrupts before + * re-enabling the default set of port interrupts. + * + * @port Pointer to the port structure. + * + * return value + * None + */ +static void mtip_init_port(struct mtip_port *port) +{ + int i; + mtip_deinit_port(port); + + /* Program the command list base and FIS base addresses */ + if (readl(port->dd->mmio + HOST_CAP) & HOST_CAP_64) { + writel((port->command_list_dma >> 16) >> 16, + port->mmio + PORT_LST_ADDR_HI); + writel((port->rxfis_dma >> 16) >> 16, + port->mmio + PORT_FIS_ADDR_HI); + } + + writel(port->command_list_dma & 0xffffffff, + port->mmio + PORT_LST_ADDR); + writel(port->rxfis_dma & 0xffffffff, port->mmio + PORT_FIS_ADDR); + + /* Clear SError */ + writel(readl(port->mmio + PORT_SCR_ERR), port->mmio + PORT_SCR_ERR); + + /* reset the completed registers.*/ + for (i = 0; i < port->dd->slot_groups; i++) + writel(0xFFFFFFFF, port->completed[i]); + + /* Clear any pending interrupts for this port */ + writel(readl(port->mmio + PORT_IRQ_STAT), port->mmio + PORT_IRQ_STAT); + + /* Enable port interrupts */ + writel(DEF_PORT_IRQ, port->mmio + PORT_IRQ_MASK); +} + +/* + * Reset the HBA (without sleeping) + * + * Just like hba_reset, except does not call sleep, so can be + * run from interrupt/tasklet context. + * + * @dd Pointer to the driver data structure. + * + * return value + * 0 The reset was successful. + * -1 The HBA Reset bit did not clear. + */ +int hba_reset_nosleep(struct driver_data *dd) +{ + unsigned long timeout; + + /* Chip quirk: quiesce any chip function */ + mdelay(10); + + /* Set the reset bit */ + writel(HOST_RESET, dd->mmio + HOST_CTL); + + /* Flush */ + readl(dd->mmio + HOST_CTL); + + /* + * Wait 10ms then spin for up to 1 second + * waiting for reset acknowledgement + */ + timeout = jiffies + msecs_to_jiffies(1000); + mdelay(10); + while ((readl(dd->mmio + HOST_CTL) & HOST_RESET) + && time_before(jiffies, timeout)) + mdelay(1); + + if (readl(dd->mmio + HOST_CTL) & HOST_RESET) + return -1; + + return 0; +} + +/* + * Restart a port + * + * @port Pointer to the port data structure. + * + * return value + * None + */ +void mtip_restart_port(struct mtip_port *port) +{ + unsigned long timeout; + + /* Disable the DMA engine */ + mtip_enable_engine(port, 0); + + /* Chip quirk: wait up to 500ms for PxCMD.CR == 0 */ + timeout = jiffies + msecs_to_jiffies(500); + while ((readl(port->mmio + PORT_CMD) & PORT_CMD_LIST_ON) + && time_before(jiffies, timeout)) + ; + + /* + * Chip quirk: escalate to hba reset if + * PxCMD.CR not clear after 500 ms + */ + if (readl(port->mmio + PORT_CMD) & PORT_CMD_LIST_ON) { + dev_warn(&port->dd->pdev->dev, + "PxCMD.CR not clear, escalating reset\n"); + + if (hba_reset_nosleep(port->dd)) + dev_err(&port->dd->pdev->dev, + "HBA reset escalation failed.\n"); + + /* 30 ms delay before com reset to quiesce chip */ + mdelay(30); + } + + dev_warn(&port->dd->pdev->dev, "Issuing COM reset\n"); + + /* Set PxSCTL.DET */ + writel(readl(port->mmio + PORT_SCR_CTL) | + 1, port->mmio + PORT_SCR_CTL); + readl(port->mmio + PORT_SCR_CTL); + + /* Wait 1 ms to quiesce chip function */ + timeout = jiffies + msecs_to_jiffies(1); + while (time_before(jiffies, timeout)) + ; + + /* Clear PxSCTL.DET */ + writel(readl(port->mmio + PORT_SCR_CTL) & ~1, + port->mmio + PORT_SCR_CTL); + readl(port->mmio + PORT_SCR_CTL); + + /* Wait 500 ms for bit 0 of PORT_SCR_STS to be set */ + timeout = jiffies + msecs_to_jiffies(500); + while (((readl(port->mmio + PORT_SCR_STAT) & 0x01) == 0) + && time_before(jiffies, timeout)) + ; + + if ((readl(port->mmio + PORT_SCR_STAT) & 0x01) == 0) + dev_warn(&port->dd->pdev->dev, + "COM reset failed\n"); + + /* Clear SError, the PxSERR.DIAG.x should be set so clear it */ + writel(readl(port->mmio + PORT_SCR_ERR), port->mmio + PORT_SCR_ERR); + + /* Enable the DMA engine */ + mtip_enable_engine(port, 1); +} + +/* + * Helper function for tag logging + */ +static void print_tags(struct driver_data *dd, + char *msg, + unsigned long *tagbits) +{ + unsigned int tag, count = 0; + + for (tag = 0; tag < (dd->slot_groups) * 32; tag++) { + if (test_bit(tag, tagbits)) + count++; + } + if (count) + dev_info(&dd->pdev->dev, "%s [%i tags]\n", msg, count); +} + +/* + * Handle an error. + * + * @dd Pointer to the DRIVER_DATA structure. + * + * return value + * None + */ +static void mtip_handle_tfe(struct driver_data *dd) +{ + int group, tag, bit, reissue; + struct mtip_port *port; + struct mtip_cmd *command; + u32 completed; + struct host_to_dev_fis *fis; + unsigned long tagaccum[SLOTBITS_IN_LONGS]; + + dev_warn(&dd->pdev->dev, "Taskfile error\n"); + + port = dd->port; + + /* Stop the timer to prevent command timeouts. */ + del_timer(&port->cmd_timer); + + /* Set eh_active */ + atomic_inc(&dd->eh_active); + + /* Loop through all the groups */ + for (group = 0; group < dd->slot_groups; group++) { + completed = readl(port->completed[group]); + + /* clear completed status register in the hardware.*/ + writel(completed, port->completed[group]); + + /* clear the tag accumulator */ + memset(tagaccum, 0, SLOTBITS_IN_LONGS * sizeof(long)); + + /* Process successfully completed commands */ + for (bit = 0; bit < 32 && completed; bit++) { + if (!(completed & (1<commands[tag]; + if (likely(command->comp_func)) { + set_bit(tag, tagaccum); + atomic_set(&port->commands[tag].active, 0); + command->comp_func(port, + tag, + command->comp_data, + 0); + } else { + dev_err(&port->dd->pdev->dev, + "Missing completion func for tag %d", + tag); + if (mtip_check_surprise_removal(dd->pdev)) { + mtip_command_cleanup(dd); + /* don't proceed further */ + return; + } + } + } + } + print_tags(dd, "TFE tags completed:", tagaccum); + + /* Restart the port */ + mdelay(20); + mtip_restart_port(port); + + /* clear the tag accumulator */ + memset(tagaccum, 0, SLOTBITS_IN_LONGS * sizeof(long)); + + /* Loop through all the groups */ + for (group = 0; group < dd->slot_groups; group++) { + for (bit = 0; bit < 32; bit++) { + reissue = 1; + tag = (group << 5) + bit; + + /* If the active bit is set re-issue the command */ + if (atomic_read(&port->commands[tag].active) == 0) + continue; + + fis = (struct host_to_dev_fis *) + port->commands[tag].command; + + /* Should re-issue? */ + if (tag == MTIP_TAG_INTERNAL || + fis->command == ATA_CMD_SET_FEATURES) + reissue = 0; + + /* + * First check if this command has + * exceeded its retries. + */ + if (reissue && + (port->commands[tag].retries-- > 0)) { + + set_bit(tag, tagaccum); + + /* Update the timeout value. */ + port->commands[tag].comp_time = + jiffies + msecs_to_jiffies( + MTIP_NCQ_COMMAND_TIMEOUT_MS); + /* Re-issue the command. */ + mtip_issue_ncq_command(port, tag); + + continue; + } + + /* Retire a command that will not be reissued */ + dev_warn(&port->dd->pdev->dev, + "retiring tag %d\n", tag); + atomic_set(&port->commands[tag].active, 0); + + if (port->commands[tag].comp_func) + port->commands[tag].comp_func( + port, + tag, + port->commands[tag].comp_data, + PORT_IRQ_TF_ERR); + else + dev_warn(&port->dd->pdev->dev, + "Bad completion for tag %d\n", + tag); + } + } + print_tags(dd, "TFE tags reissued:", tagaccum); + + /* Decrement eh_active */ + atomic_dec(&dd->eh_active); + + mod_timer(&port->cmd_timer, + jiffies + msecs_to_jiffies(MTIP_TIMEOUT_CHECK_PERIOD)); +} + +/* + * Handle a set device bits interrupt + */ +static inline void mtip_process_sdbf(struct driver_data *dd) +{ + struct mtip_port *port = dd->port; + int group, tag, bit; + u32 completed; + struct mtip_cmd *command; + + /* walk all bits in all slot groups */ + for (group = 0; group < dd->slot_groups; group++) { + completed = readl(port->completed[group]); + + /* clear completed status register in the hardware.*/ + writel(completed, port->completed[group]); + + /* Process completed commands. */ + for (bit = 0; + (bit < 32) && completed; + bit++, completed >>= 1) { + if (completed & 0x01) { + tag = (group << 5) | bit; + + /* skip internal command slot. */ + if (unlikely(tag == MTIP_TAG_INTERNAL)) + continue; + + command = &port->commands[tag]; + + /* make internal callback */ + if (likely(command->comp_func)) { + command->comp_func( + port, + tag, + command->comp_data, + 0); + } else { + dev_warn(&dd->pdev->dev, + "Null completion " + "for tag %d", + tag); + + if (mtip_check_surprise_removal( + dd->pdev)) { + mtip_command_cleanup(dd); + return; + } + } + } + } + } +} + +/* + * Process legacy pio and d2h interrupts + */ +static inline void mtip_process_legacy(struct driver_data *dd, u32 port_stat) +{ + struct mtip_port *port = dd->port; + struct mtip_cmd *cmd = &port->commands[MTIP_TAG_INTERNAL]; + + if (port->internal_cmd_in_progress && + cmd != NULL && + !(readl(port->cmd_issue[MTIP_TAG_INTERNAL]) + & (1 << MTIP_TAG_INTERNAL))) { + if (cmd->comp_func) { + cmd->comp_func(port, + MTIP_TAG_INTERNAL, + cmd->comp_data, + 0); + return; + } + } + + dev_warn(&dd->pdev->dev, "IRQ status 0x%x ignored.\n", port_stat); + + return; +} + +/* + * Demux and handle errors + */ +static inline void mtip_process_errors(struct driver_data *dd, u32 port_stat) +{ + if (likely(port_stat & (PORT_IRQ_TF_ERR | PORT_IRQ_IF_ERR))) + mtip_handle_tfe(dd); + + if (unlikely(port_stat & PORT_IRQ_CONNECT)) { + dev_warn(&dd->pdev->dev, + "Clearing PxSERR.DIAG.x\n"); + writel((1 << 26), dd->port->mmio + PORT_SCR_ERR); + } + + if (unlikely(port_stat & PORT_IRQ_PHYRDY)) { + dev_warn(&dd->pdev->dev, + "Clearing PxSERR.DIAG.n\n"); + writel((1 << 16), dd->port->mmio + PORT_SCR_ERR); + } + + if (unlikely(port_stat & ~PORT_IRQ_HANDLED)) { + dev_warn(&dd->pdev->dev, + "Port stat errors %x unhandled\n", + (port_stat & ~PORT_IRQ_HANDLED)); + } +} + +static inline irqreturn_t mtip_handle_irq(struct driver_data *data) +{ + struct driver_data *dd = (struct driver_data *) data; + struct mtip_port *port = dd->port; + u32 hba_stat, port_stat; + int rv = IRQ_NONE; + + hba_stat = readl(dd->mmio + HOST_IRQ_STAT); + if (hba_stat) { + rv = IRQ_HANDLED; + + /* Acknowledge the interrupt status on the port.*/ + port_stat = readl(port->mmio + PORT_IRQ_STAT); + writel(port_stat, port->mmio + PORT_IRQ_STAT); + + /* Demux port status */ + if (likely(port_stat & PORT_IRQ_SDB_FIS)) + mtip_process_sdbf(dd); + + if (unlikely(port_stat & PORT_IRQ_ERR)) { + if (unlikely(mtip_check_surprise_removal(dd->pdev))) { + mtip_command_cleanup(dd); + /* don't proceed further */ + return IRQ_HANDLED; + } + + mtip_process_errors(dd, port_stat & PORT_IRQ_ERR); + } + + if (unlikely(port_stat & PORT_IRQ_LEGACY)) + mtip_process_legacy(dd, port_stat & PORT_IRQ_LEGACY); + } + + /* acknowledge interrupt */ + writel(hba_stat, dd->mmio + HOST_IRQ_STAT); + + return rv; +} + +/* + * Wrapper for mtip_handle_irq + * (ignores return code) + */ +static void mtip_tasklet(unsigned long data) +{ + mtip_handle_irq((struct driver_data *) data); +} + +/* + * HBA interrupt subroutine. + * + * @irq IRQ number. + * @instance Pointer to the driver data structure. + * + * return value + * IRQ_HANDLED A HBA interrupt was pending and handled. + * IRQ_NONE This interrupt was not for the HBA. + */ +static irqreturn_t mtip_irq_handler(int irq, void *instance) +{ + struct driver_data *dd = instance; + tasklet_schedule(&dd->tasklet); + return IRQ_HANDLED; +} + +static void mtip_issue_non_ncq_command(struct mtip_port *port, int tag) +{ + atomic_set(&port->commands[tag].active, 1); + writel(1 << MTIP_TAG_BIT(tag), + port->cmd_issue[MTIP_TAG_INDEX(tag)]); +} + +/* + * Wait for port to quiesce + * + * @port Pointer to port data structure + * @timeout Max duration to wait (ms) + * + * return value + * 0 Success + * -EBUSY Commands still active + */ +static int mtip_quiesce_io(struct mtip_port *port, unsigned long timeout) +{ + unsigned long to; + unsigned int n, active; + + to = jiffies + msecs_to_jiffies(timeout); + do { + /* + * Ignore s_active bit 0 of array element 0. + * This bit will always be set + */ + active = readl(port->s_active[0]) & 0xfffffffe; + for (n = 1; n < port->dd->slot_groups; n++) + active |= readl(port->s_active[n]); + + if (!active) + break; + + msleep(20); + } while (time_before(jiffies, to)); + + return active ? -EBUSY : 0; +} + +/* + * Execute an internal command and wait for the completion. + * + * @port Pointer to the port data structure. + * @fis Pointer to the FIS that describes the command. + * @fisLen Length in WORDS of the FIS. + * @buffer DMA accessible for command data. + * @bufLen Length, in bytes, of the data buffer. + * @opts Command header options, excluding the FIS length + * and the number of PRD entries. + * @timeout Time in ms to wait for the command to complete. + * + * return value + * 0 Command completed successfully. + * -EFAULT The buffer address is not correctly aligned. + * -EBUSY Internal command or other IO in progress. + * -EAGAIN Time out waiting for command to complete. + */ +static int mtip_exec_internal_command(struct mtip_port *port, + void *fis, + int fisLen, + dma_addr_t buffer, + int bufLen, + u32 opts, + gfp_t atomic, + unsigned long timeout) +{ + struct mtip_cmd_sg *command_sg; + DECLARE_COMPLETION_ONSTACK(wait); + int rv = 0; + struct mtip_cmd *int_cmd = &port->commands[MTIP_TAG_INTERNAL]; + + /* Make sure the buffer is 8 byte aligned. This is asic specific. */ + if (buffer & 0x00000007) { + dev_err(&port->dd->pdev->dev, + "SG buffer is not 8 byte aligned\n"); + return -EFAULT; + } + + /* Only one internal command should be running at a time */ + if (test_and_set_bit(MTIP_TAG_INTERNAL, port->allocated)) { + dev_warn(&port->dd->pdev->dev, + "Internal command already active\n"); + return -EBUSY; + } + port->internal_cmd_in_progress = 1; + + if (atomic == GFP_KERNEL) { + /* wait for io to complete if non atomic */ + if (mtip_quiesce_io(port, 5000) < 0) { + dev_warn(&port->dd->pdev->dev, + "Failed to quiesce IO\n"); + release_slot(port, MTIP_TAG_INTERNAL); + port->internal_cmd_in_progress = 0; + return -EBUSY; + } + + /* Set the completion function and data for the command. */ + int_cmd->comp_data = &wait; + int_cmd->comp_func = mtip_completion; + + } else { + /* Clear completion - we're going to poll */ + int_cmd->comp_data = NULL; + int_cmd->comp_func = NULL; + } + + /* Copy the command to the command table */ + memcpy(int_cmd->command, fis, fisLen*4); + + /* Populate the SG list */ + int_cmd->command_header->opts = + cpu_to_le32(opts | fisLen); + if (bufLen) { + command_sg = int_cmd->command + AHCI_CMD_TBL_HDR_SZ; + + command_sg->info = cpu_to_le32((bufLen-1) & 0x3fffff); + command_sg->dba = cpu_to_le32(buffer & 0xffffffff); + command_sg->dba_upper = cpu_to_le32((buffer >> 16) >> 16); + + int_cmd->command_header->opts |= cpu_to_le32((1 << 16)); + } + + /* Populate the command header */ + int_cmd->command_header->byte_count = 0; + + /* Issue the command to the hardware */ + mtip_issue_non_ncq_command(port, MTIP_TAG_INTERNAL); + + /* Poll if atomic, wait_for_completion otherwise */ + if (atomic == GFP_KERNEL) { + /* Wait for the command to complete or timeout. */ + if (wait_for_completion_timeout( + &wait, + msecs_to_jiffies(timeout)) == 0) { + dev_err(&port->dd->pdev->dev, + "Internal command did not complete [%d]\n", + atomic); + rv = -EAGAIN; + } + + if (readl(port->cmd_issue[MTIP_TAG_INTERNAL]) + & (1 << MTIP_TAG_INTERNAL)) { + dev_warn(&port->dd->pdev->dev, + "Retiring internal command but CI is 1.\n"); + } + + } else { + /* Spin for checking if command still outstanding */ + timeout = jiffies + msecs_to_jiffies(timeout); + + while ((readl( + port->cmd_issue[MTIP_TAG_INTERNAL]) + & (1 << MTIP_TAG_INTERNAL)) + && time_before(jiffies, timeout)) + ; + + if (readl(port->cmd_issue[MTIP_TAG_INTERNAL]) + & (1 << MTIP_TAG_INTERNAL)) { + dev_err(&port->dd->pdev->dev, + "Internal command did not complete [%d]\n", + atomic); + rv = -EAGAIN; + } + } + + /* Clear the allocated and active bits for the internal command. */ + atomic_set(&int_cmd->active, 0); + release_slot(port, MTIP_TAG_INTERNAL); + port->internal_cmd_in_progress = 0; + + return rv; +} + +/* + * Byte-swap ATA ID strings. + * + * ATA identify data contains strings in byte-swapped 16-bit words. + * They must be swapped (on all architectures) to be usable as C strings. + * This function swaps bytes in-place. + * + * @buf The buffer location of the string + * @len The number of bytes to swap + * + * return value + * None + */ +static inline void ata_swap_string(u16 *buf, unsigned int len) +{ + int i; + for (i = 0; i < (len/2); i++) + be16_to_cpus(&buf[i]); +} + +/* + * Request the device identity information. + * + * If a user space buffer is not specified, i.e. is NULL, the + * identify information is still read from the drive and placed + * into the identify data buffer (@e port->identify) in the + * port data structure. + * When the identify buffer contains valid identify information @e + * port->identify_valid is non-zero. + * + * @port Pointer to the port structure. + * @user_buffer A user space buffer where the identify data should be + * copied. + * + * return value + * 0 Command completed successfully. + * -EFAULT An error occurred while coping data to the user buffer. + * -1 Command failed. + */ +static int mtip_get_identify(struct mtip_port *port, void __user *user_buffer) +{ + int rv = 0; + struct host_to_dev_fis fis; + + down_write(&port->dd->internal_sem); + + /* Build the FIS. */ + memset(&fis, 0, sizeof(struct host_to_dev_fis)); + fis.type = 0x27; + fis.opts = 1 << 7; + fis.command = ATA_CMD_ID_ATA; + + /* Set the identify information as invalid. */ + port->identify_valid = 0; + + /* Clear the identify information. */ + memset(port->identify, 0, sizeof(u16) * ATA_ID_WORDS); + + /* Execute the command. */ + if (mtip_exec_internal_command(port, + &fis, + 5, + port->identify_dma, + sizeof(u16) * ATA_ID_WORDS, + 0, + GFP_KERNEL, + MTIP_INTERNAL_COMMAND_TIMEOUT_MS) + < 0) { + rv = -1; + goto out; + } + + /* + * Perform any necessary byte-swapping. Yes, the kernel does in fact + * perform field-sensitive swapping on the string fields. + * See the kernel use of ata_id_string() for proof of this. + */ +#ifdef __LITTLE_ENDIAN + ata_swap_string(port->identify + 27, 40); /* model string*/ + ata_swap_string(port->identify + 23, 8); /* firmware string*/ + ata_swap_string(port->identify + 10, 20); /* serial# string*/ +#else + { + int i; + for (i = 0; i < ATA_ID_WORDS; i++) + port->identify[i] = le16_to_cpu(port->identify[i]); + } +#endif + + /* Set the identify buffer as valid. */ + port->identify_valid = 1; + + if (user_buffer) { + if (copy_to_user( + user_buffer, + port->identify, + ATA_ID_WORDS * sizeof(u16))) { + rv = -EFAULT; + goto out; + } + } + +out: + up_write(&port->dd->internal_sem); + return rv; +} + +/* + * Issue a standby immediate command to the device. + * + * @port Pointer to the port structure. + * + * return value + * 0 Command was executed successfully. + * -1 An error occurred while executing the command. + */ +static int mtip_standby_immediate(struct mtip_port *port) +{ + int rv; + struct host_to_dev_fis fis; + + down_write(&port->dd->internal_sem); + + /* Build the FIS. */ + memset(&fis, 0, sizeof(struct host_to_dev_fis)); + fis.type = 0x27; + fis.opts = 1 << 7; + fis.command = ATA_CMD_STANDBYNOW1; + + /* Execute the command. Use a 15-second timeout for large drives. */ + rv = mtip_exec_internal_command(port, + &fis, + 5, + 0, + 0, + 0, + GFP_KERNEL, + 15000); + + up_write(&port->dd->internal_sem); + + return rv; +} + +/* + * Get the drive capacity. + * + * @dd Pointer to the device data structure. + * @sectors Pointer to the variable that will receive the sector count. + * + * return value + * 1 Capacity was returned successfully. + * 0 The identify information is invalid. + */ +bool mtip_hw_get_capacity(struct driver_data *dd, sector_t *sectors) +{ + struct mtip_port *port = dd->port; + u64 total, raw0, raw1, raw2, raw3; + raw0 = port->identify[100]; + raw1 = port->identify[101]; + raw2 = port->identify[102]; + raw3 = port->identify[103]; + total = raw0 | raw1<<16 | raw2<<32 | raw3<<48; + *sectors = total; + return (bool) !!port->identify_valid; +} + +/* + * Reset the HBA. + * + * Resets the HBA by setting the HBA Reset bit in the Global + * HBA Control register. After setting the HBA Reset bit the + * function waits for 1 second before reading the HBA Reset + * bit to make sure it has cleared. If HBA Reset is not clear + * an error is returned. Cannot be used in non-blockable + * context. + * + * @dd Pointer to the driver data structure. + * + * return value + * 0 The reset was successful. + * -1 The HBA Reset bit did not clear. + */ +static int mtip_hba_reset(struct driver_data *dd) +{ + mtip_deinit_port(dd->port); + + /* Set the reset bit */ + writel(HOST_RESET, dd->mmio + HOST_CTL); + + /* Flush */ + readl(dd->mmio + HOST_CTL); + + /* Wait for reset to clear */ + ssleep(1); + + /* Check the bit has cleared */ + if (readl(dd->mmio + HOST_CTL) & HOST_RESET) { + dev_err(&dd->pdev->dev, + "Reset bit did not clear.\n"); + return -1; + } + + return 0; +} + +/* + * Display the identify command data. + * + * @port Pointer to the port data structure. + * + * return value + * None + */ +static void mtip_dump_identify(struct mtip_port *port) +{ + sector_t sectors; + unsigned short revid; + char cbuf[42]; + + if (!port->identify_valid) + return; + + strlcpy(cbuf, (char *)(port->identify+10), 21); + dev_info(&port->dd->pdev->dev, + "Serial No.: %s\n", cbuf); + + strlcpy(cbuf, (char *)(port->identify+23), 9); + dev_info(&port->dd->pdev->dev, + "Firmware Ver.: %s\n", cbuf); + + strlcpy(cbuf, (char *)(port->identify+27), 41); + dev_info(&port->dd->pdev->dev, "Model: %s\n", cbuf); + + if (mtip_hw_get_capacity(port->dd, §ors)) + dev_info(&port->dd->pdev->dev, + "Capacity: %llu sectors (%llu MB)\n", + (u64)sectors, + ((u64)sectors) * ATA_SECT_SIZE >> 20); + + pci_read_config_word(port->dd->pdev, PCI_REVISION_ID, &revid); + switch (revid & 0xff) { + case 0x1: + strlcpy(cbuf, "A0", 3); + break; + case 0x3: + strlcpy(cbuf, "A2", 3); + break; + default: + strlcpy(cbuf, "?", 2); + break; + } + dev_info(&port->dd->pdev->dev, + "Card Type: %s\n", cbuf); +} + +/* + * Map the commands scatter list into the command table. + * + * @command Pointer to the command. + * @nents Number of scatter list entries. + * + * return value + * None + */ +static inline void fill_command_sg(struct driver_data *dd, + struct mtip_cmd *command, + int nents) +{ + int n; + unsigned int dma_len; + struct mtip_cmd_sg *command_sg; + struct scatterlist *sg = command->sg; + + command_sg = command->command + AHCI_CMD_TBL_HDR_SZ; + + for (n = 0; n < nents; n++) { + dma_len = sg_dma_len(sg); + if (dma_len > 0x400000) + dev_err(&dd->pdev->dev, + "DMA segment length truncated\n"); + command_sg->info = cpu_to_le32((dma_len-1) & 0x3fffff); +#if (BITS_PER_LONG == 64) + *((unsigned long *) &command_sg->dba) = + cpu_to_le64(sg_dma_address(sg)); +#else + command_sg->dba = cpu_to_le32(sg_dma_address(sg)); + command_sg->dba_upper = + cpu_to_le32((sg_dma_address(sg) >> 16) >> 16); +#endif + command_sg++; + sg++; + } +} + +/* + * @brief Execute a drive command. + * + * return value 0 The command completed successfully. + * return value -1 An error occurred while executing the command. + */ +int exec_drive_task(struct mtip_port *port, u8 *command) +{ + struct host_to_dev_fis fis; + struct host_to_dev_fis *reply = (port->rxfis + RX_FIS_D2H_REG); + + /* Lock the internal command semaphore. */ + down_write(&port->dd->internal_sem); + + /* Build the FIS. */ + memset(&fis, 0, sizeof(struct host_to_dev_fis)); + fis.type = 0x27; + fis.opts = 1 << 7; + fis.command = command[0]; + fis.features = command[1]; + fis.sect_count = command[2]; + fis.sector = command[3]; + fis.cyl_low = command[4]; + fis.cyl_hi = command[5]; + fis.device = command[6] & ~0x10; /* Clear the dev bit*/ + + + dbg_printk(MTIP_DRV_NAME "%s: User Command: cmd %x, feat %x, " + "nsect %x, sect %x, lcyl %x, " + "hcyl %x, sel %x\n", + __func__, + command[0], + command[1], + command[2], + command[3], + command[4], + command[5], + command[6]); + + /* Execute the command. */ + if (mtip_exec_internal_command(port, + &fis, + 5, + 0, + 0, + 0, + GFP_KERNEL, + MTIP_IOCTL_COMMAND_TIMEOUT_MS) < 0) { + up_write(&port->dd->internal_sem); + return -1; + } + + command[0] = reply->command; /* Status*/ + command[1] = reply->features; /* Error*/ + command[4] = reply->cyl_low; + command[5] = reply->cyl_hi; + + dbg_printk(MTIP_DRV_NAME "%s: Completion Status: stat %x, " + "err %x , cyl_lo %x cyl_hi %x\n", + __func__, + command[0], + command[1], + command[4], + command[5]); + + up_write(&port->dd->internal_sem); + return 0; +} + +/* + * @brief Execute a drive command. + * + * @param port Pointer to the port data structure. + * @param command Pointer to the user specified command parameters. + * @param user_buffer Pointer to the user space buffer where read sector + * data should be copied. + * + * return value 0 The command completed successfully. + * return value -EFAULT An error occurred while copying the completion + * data to the user space buffer. + * return value -1 An error occurred while executing the command. + */ +int exec_drive_command(struct mtip_port *port, u8 *command, + void __user *user_buffer) +{ + struct host_to_dev_fis fis; + struct host_to_dev_fis *reply = (port->rxfis + RX_FIS_D2H_REG); + + /* Lock the internal command semaphore. */ + down_write(&port->dd->internal_sem); + + /* Build the FIS. */ + memset(&fis, 0, sizeof(struct host_to_dev_fis)); + fis.type = 0x27; + fis.opts = 1 << 7; + fis.command = command[0]; + fis.features = command[2]; + fis.sect_count = command[3]; + if (fis.command == ATA_CMD_SMART) { + fis.sector = command[1]; + fis.cyl_low = 0x4f; + fis.cyl_hi = 0xc2; + } + + dbg_printk(MTIP_DRV_NAME + "%s: User Command: cmd %x, sect %x, " + "feat %x, sectcnt %x\n", + __func__, + command[0], + command[1], + command[2], + command[3]); + + memset(port->sector_buffer, 0x00, ATA_SECT_SIZE); + + /* Execute the command. */ + if (mtip_exec_internal_command(port, + &fis, + 5, + port->sector_buffer_dma, + (command[3] != 0) ? ATA_SECT_SIZE : 0, + 0, + GFP_KERNEL, + MTIP_IOCTL_COMMAND_TIMEOUT_MS) + < 0) { + up_write(&port->dd->internal_sem); + return -1; + } + + /* Collect the completion status. */ + command[0] = reply->command; /* Status*/ + command[1] = reply->features; /* Error*/ + command[2] = command[3]; + + dbg_printk(MTIP_DRV_NAME + "%s: Completion Status: stat %x, " + "err %x, cmd %x\n", + __func__, + command[0], + command[1], + command[2]); + + if (user_buffer && command[3]) { + if (copy_to_user(user_buffer, + port->sector_buffer, + ATA_SECT_SIZE * command[3])) { + up_write(&port->dd->internal_sem); + return -EFAULT; + } + } + + up_write(&port->dd->internal_sem); + return 0; +} + +/* + * Indicates whether a command has a single sector payload. + * + * @command passed to the device to perform the certain event. + * @features passed to the device to perform the certain event. + * + * return value + * 1 command is one that always has a single sector payload, + * regardless of the value in the Sector Count field. + * 0 otherwise + * + */ +static unsigned int implicit_sector(unsigned char command, + unsigned char features) +{ + unsigned int rv = 0; + + /* list of commands that have an implicit sector count of 1 */ + switch (command) { + case 0xF1: + case 0xF2: + case 0xF3: + case 0xF4: + case 0xF5: + case 0xF6: + case 0xE4: + case 0xE8: + rv = 1; + break; + case 0xF9: + if (features == 0x03) + rv = 1; + break; + case 0xB0: + if ((features == 0xD0) || (features == 0xD1)) + rv = 1; + break; + case 0xB1: + if ((features == 0xC2) || (features == 0xC3)) + rv = 1; + break; + } + return rv; +} + +/* + * Executes a taskfile + * See ide_taskfile_ioctl() for derivation + */ +static int exec_drive_taskfile(struct driver_data *dd, + unsigned long arg, + unsigned char compat) +{ + struct host_to_dev_fis fis; + struct host_to_dev_fis *reply; + ide_task_request_t *req_task; + u8 *outbuf = NULL; + u8 *inbuf = NULL; + dma_addr_t outbuf_dma = (dma_addr_t)NULL; + dma_addr_t inbuf_dma = (dma_addr_t)NULL; + dma_addr_t dma_buffer = (dma_addr_t)NULL; + int err = 0; + int tasksize = sizeof(struct ide_task_request_s); + unsigned int taskin = 0; + unsigned int taskout = 0; + u8 nsect = 0; + char __user *buf = (char __user *)arg; + unsigned int timeout = MTIP_IOCTL_COMMAND_TIMEOUT_MS; + unsigned int force_single_sector; + unsigned int transfer_size; + unsigned long task_file_data; + int intotal, outtotal; + struct mtip_compat_ide_task_request_s *compat_req_task = NULL; + int compat_tasksize = sizeof(struct mtip_compat_ide_task_request_s); + + req_task = kzalloc(tasksize, GFP_KERNEL); + if (req_task == NULL) + return -ENOMEM; + + if (compat == 1) { + compat_req_task = + (struct mtip_compat_ide_task_request_s __user *) arg; + + if (copy_from_user(req_task, buf, + compat_tasksize - + (2 * sizeof(compat_long_t)))) { + err = -EFAULT; + goto abort; + } + + if (get_user(req_task->out_size, &compat_req_task->out_size)) { + err = -EFAULT; + goto abort; + } + + if (get_user(req_task->in_size, &compat_req_task->in_size)) { + err = -EFAULT; + goto abort; + } + + outtotal = compat_tasksize; + intotal = compat_tasksize + req_task->out_size; + } else { + if (copy_from_user(req_task, buf, tasksize)) { + kfree(req_task); + err = -EFAULT; + goto abort; + } + + outtotal = tasksize; + intotal = tasksize + req_task->out_size; + } + + taskout = req_task->out_size; + taskin = req_task->in_size; + /* 130560 = 512 * 0xFF*/ + if (taskin > 130560 || taskout > 130560) { + err = -EINVAL; + goto abort; + } + + if (taskout) { + outbuf = kzalloc(taskout, GFP_KERNEL); + if (outbuf == NULL) { + err = -ENOMEM; + goto abort; + } + if (copy_from_user(outbuf, buf + outtotal, taskout)) { + err = -EFAULT; + goto abort; + } + outbuf_dma = pci_map_single(dd->pdev, + outbuf, + taskout, + DMA_TO_DEVICE); + if (outbuf_dma == (dma_addr_t)NULL) { + err = -ENOMEM; + goto abort; + } + dma_buffer = outbuf_dma; + } + + if (taskin) { + inbuf = kzalloc(taskin, GFP_KERNEL); + if (inbuf == NULL) { + err = -ENOMEM; + goto abort; + } + + if (copy_from_user(inbuf, buf + intotal, taskin)) { + err = -EFAULT; + goto abort; + } + inbuf_dma = pci_map_single(dd->pdev, + inbuf, + taskin, DMA_FROM_DEVICE); + if (inbuf_dma == (dma_addr_t)NULL) { + err = -ENOMEM; + goto abort; + } + dma_buffer = inbuf_dma; + } + + /* only supports PIO and non-data commands from this ioctl. */ + switch (req_task->data_phase) { + case TASKFILE_OUT: + nsect = taskout / ATA_SECT_SIZE; + reply = (dd->port->rxfis + RX_FIS_PIO_SETUP); + break; + case TASKFILE_IN: + reply = (dd->port->rxfis + RX_FIS_PIO_SETUP); + break; + case TASKFILE_NO_DATA: + reply = (dd->port->rxfis + RX_FIS_D2H_REG); + break; + default: + err = -EINVAL; + goto abort; + } + + /* Lock the internal command semaphore. */ + down_write(&dd->internal_sem); + + /* Build the FIS. */ + memset(&fis, 0, sizeof(struct host_to_dev_fis)); + + fis.type = 0x27; + fis.opts = 1 << 7; + fis.command = req_task->io_ports[7]; + fis.features = req_task->io_ports[1]; + fis.sect_count = req_task->io_ports[2]; + fis.lba_low = req_task->io_ports[3]; + fis.lba_mid = req_task->io_ports[4]; + fis.lba_hi = req_task->io_ports[5]; + /* Clear the dev bit*/ + fis.device = req_task->io_ports[6] & ~0x10; + + if ((req_task->in_flags.all == 0) && (req_task->out_flags.all & 1)) { + req_task->in_flags.all = + IDE_TASKFILE_STD_IN_FLAGS | + (IDE_HOB_STD_IN_FLAGS << 8); + fis.lba_low_ex = req_task->hob_ports[3]; + fis.lba_mid_ex = req_task->hob_ports[4]; + fis.lba_hi_ex = req_task->hob_ports[5]; + fis.features_ex = req_task->hob_ports[1]; + fis.sect_cnt_ex = req_task->hob_ports[2]; + + } else { + req_task->in_flags.all = IDE_TASKFILE_STD_IN_FLAGS; + } + + force_single_sector = implicit_sector(fis.command, fis.features); + + if ((taskin || taskout) && (!fis.sect_count)) { + if (nsect) + fis.sect_count = nsect; + else { + if (!force_single_sector) { + dev_warn(&dd->pdev->dev, + "data movement but " + "sect_count is 0\n"); + up_write(&dd->internal_sem); + err = -EINVAL; + goto abort; + } + } + } + + dbg_printk(MTIP_DRV_NAME + "taskfile: cmd %x, feat %x, nsect %x," + " sect/lbal %x, lcyl/lbam %x, hcyl/lbah %x," + " head/dev %x\n", + fis.command, + fis.features, + fis.sect_count, + fis.lba_low, + fis.lba_mid, + fis.lba_hi, + fis.device); + + switch (fis.command) { + case 0x92: /* Change timeout for Download Microcode to 60 seconds.*/ + timeout = 60000; + break; + case 0xf4: /* Change timeout for Security Erase Unit to 4 minutes.*/ + timeout = 240000; + break; + case 0xe0: /* Change timeout for standby immediate to 10 seconds.*/ + timeout = 10000; + break; + case 0xf7: /* Change timeout for vendor unique command to 10 secs */ + timeout = 10000; + break; + case 0xfa: /* Change timeout for vendor unique command to 10 secs */ + timeout = 10000; + break; + default: + timeout = MTIP_IOCTL_COMMAND_TIMEOUT_MS; + break; + } + + /* Determine the correct transfer size.*/ + if (force_single_sector) + transfer_size = ATA_SECT_SIZE; + else + transfer_size = ATA_SECT_SIZE * fis.sect_count; + + /* Execute the command.*/ + if (mtip_exec_internal_command(dd->port, + &fis, + 5, + dma_buffer, + transfer_size, + 0, + GFP_KERNEL, + timeout) < 0) { + up_write(&dd->internal_sem); + err = -EIO; + goto abort; + } + + task_file_data = readl(dd->port->mmio+PORT_TFDATA); + + if ((req_task->data_phase == TASKFILE_IN) && !(task_file_data & 1)) { + reply = dd->port->rxfis + RX_FIS_PIO_SETUP; + req_task->io_ports[7] = reply->control; + } else { + reply = dd->port->rxfis + RX_FIS_D2H_REG; + req_task->io_ports[7] = reply->command; + } + + /* reclaim the DMA buffers.*/ + if (inbuf_dma) + pci_unmap_single(dd->pdev, inbuf_dma, + taskin, DMA_FROM_DEVICE); + if (outbuf_dma) + pci_unmap_single(dd->pdev, outbuf_dma, + taskout, DMA_TO_DEVICE); + inbuf_dma = (dma_addr_t) NULL; + outbuf_dma = (dma_addr_t) NULL; + + /* return the ATA registers to the caller.*/ + req_task->io_ports[1] = reply->features; + req_task->io_ports[2] = reply->sect_count; + req_task->io_ports[3] = reply->lba_low; + req_task->io_ports[4] = reply->lba_mid; + req_task->io_ports[5] = reply->lba_hi; + req_task->io_ports[6] = reply->device; + + if (req_task->out_flags.all & 1) { + + req_task->hob_ports[3] = reply->lba_low_ex; + req_task->hob_ports[4] = reply->lba_mid_ex; + req_task->hob_ports[5] = reply->lba_hi_ex; + req_task->hob_ports[1] = reply->features_ex; + req_task->hob_ports[2] = reply->sect_cnt_ex; + } + + /* Com rest after secure erase or lowlevel format */ + if (((fis.command == 0xF4) || + ((fis.command == 0xFC) && + (fis.features == 0x27 || fis.features == 0x72 || + fis.features == 0x62 || fis.features == 0x26))) && + !(reply->command & 1)) { + mtip_restart_port(dd->port); + } + + dbg_printk(MTIP_DRV_NAME + "%s: Completion: stat %x," + "err %x, sect_cnt %x, lbalo %x," + "lbamid %x, lbahi %x, dev %x\n", + __func__, + req_task->io_ports[7], + req_task->io_ports[1], + req_task->io_ports[2], + req_task->io_ports[3], + req_task->io_ports[4], + req_task->io_ports[5], + req_task->io_ports[6]); + + up_write(&dd->internal_sem); + + if (compat == 1) { + if (copy_to_user(buf, req_task, + compat_tasksize - + (2 * sizeof(compat_long_t)))) { + err = -EFAULT; + goto abort; + } + if (put_user(req_task->out_size, + &compat_req_task->out_size)) { + err = -EFAULT; + goto abort; + } + if (put_user(req_task->in_size, &compat_req_task->in_size)) { + err = -EFAULT; + goto abort; + } + } else { + if (copy_to_user(buf, req_task, tasksize)) { + err = -EFAULT; + goto abort; + } + } + if (taskout) { + if (copy_to_user(buf + outtotal, outbuf, taskout)) { + err = -EFAULT; + goto abort; + } + } + if (taskin) { + if (copy_to_user(buf + intotal, inbuf, taskin)) { + err = -EFAULT; + goto abort; + } + } +abort: + if (inbuf_dma) + pci_unmap_single(dd->pdev, inbuf_dma, + taskin, DMA_FROM_DEVICE); + if (outbuf_dma) + pci_unmap_single(dd->pdev, outbuf_dma, + taskout, DMA_TO_DEVICE); + kfree(req_task); + kfree(outbuf); + kfree(inbuf); + + return err; +} + +/* + * Handle IOCTL calls from the Block Layer. + * + * This function is called by the Block Layer when it receives an IOCTL + * command that it does not understand. If the IOCTL command is not supported + * this function returns -ENOTTY. + * + * @dd Pointer to the driver data structure. + * @cmd IOCTL command passed from the Block Layer. + * @arg IOCTL argument passed from the Block Layer. + * + * return value + * 0 The IOCTL completed successfully. + * -ENOTTY The specified command is not supported. + * -EFAULT An error occurred copying data to a user space buffer. + * -EIO An error occurred while executing the command. + */ +int mtip_hw_ioctl(struct driver_data *dd, + unsigned int cmd, + unsigned long arg, + unsigned char compat) +{ + switch (cmd) { + case HDIO_GET_IDENTITY: + if (mtip_get_identify(dd->port, (void __user *) arg) < 0) { + dev_warn(&dd->pdev->dev, + "Unable to read identity\n"); + return -EIO; + } + + break; + case HDIO_DRIVE_CMD: + { + u8 drive_command[4]; + + /* Copy the user command info to our buffer. */ + if (copy_from_user(drive_command, + (void __user *) arg, + sizeof(drive_command))) + return -EFAULT; + + /* Execute the drive command. */ + if (exec_drive_command(dd->port, + drive_command, + (void __user *) (arg+4))) + return -EIO; + + /* Copy the status back to the users buffer. */ + if (copy_to_user((void __user *) arg, + drive_command, + sizeof(drive_command))) + return -EFAULT; + + break; + } + case HDIO_DRIVE_TASK: + { + u8 drive_command[7]; + + /* Copy the user command info to our buffer. */ + if (copy_from_user(drive_command, + (void __user *) arg, + sizeof(drive_command))) + return -EFAULT; + + /* Execute the drive command. */ + if (exec_drive_task(dd->port, drive_command)) + return -EIO; + + /* Copy the status back to the users buffer. */ + if (copy_to_user((void __user *) arg, + drive_command, + sizeof(drive_command))) + return -EFAULT; + + break; + } + case HDIO_DRIVE_TASKFILE: + return exec_drive_taskfile(dd, arg, compat); + + default: + return -EINVAL; + } + return 0; +} + +/* + * Submit an IO to the hw + * + * This function is called by the block layer to issue an io + * to the device. Upon completion, the callback function will + * be called with the data parameter passed as the callback data. + * + * @dd Pointer to the driver data structure. + * @start First sector to read. + * @nsect Number of sectors to read. + * @nents Number of entries in scatter list for the read command. + * @tag The tag of this read command. + * @callback Pointer to the function that should be called + * when the read completes. + * @data Callback data passed to the callback function + * when the read completes. + * @barrier If non-zero, this command must be completed before + * issuing any other commands. + * @dir Direction (read or write) + * + * return value + * None + */ +void mtip_hw_submit_io(struct driver_data *dd, + sector_t start, + int nsect, + int nents, + int tag, + void *callback, + void *data, + int barrier, + int dir) +{ + struct host_to_dev_fis *fis; + struct mtip_port *port = dd->port; + struct mtip_cmd *command = &port->commands[tag]; + + /* Map the scatter list for DMA access */ + if (dir == READ) + nents = dma_map_sg(&dd->pdev->dev, command->sg, + nents, DMA_FROM_DEVICE); + else + nents = dma_map_sg(&dd->pdev->dev, command->sg, + nents, DMA_TO_DEVICE); + + command->scatter_ents = nents; + + /* + * The number of retries for this command before it is + * reported as a failure to the upper layers. + */ + command->retries = MTIP_MAX_RETRIES; + + /* Fill out fis */ + fis = command->command; + fis->type = 0x27; + fis->opts = 1 << 7; + fis->command = + (dir == READ ? ATA_CMD_FPDMA_READ : ATA_CMD_FPDMA_WRITE); + *((unsigned int *) &fis->lba_low) = (start & 0xffffff); + *((unsigned int *) &fis->lba_low_ex) = ((start >> 24) & 0xffffff); + fis->device = 1 << 6; + if (barrier) + fis->device |= FUA_BIT; + fis->features = nsect & 0xff; + fis->features_ex = (nsect >> 8) & 0xff; + fis->sect_count = ((tag << 3) | (tag >> 5)); + fis->sect_cnt_ex = 0; + fis->control = 0; + fis->res2 = 0; + fis->res3 = 0; + fill_command_sg(dd, command, nents); + + /* Populate the command header */ + command->command_header->opts = cpu_to_le32( + (nents << 16) | 5 | AHCI_CMD_PREFETCH); + command->command_header->byte_count = 0; + + /* + * Set the completion function and data for the command + * within this layer. + */ + command->comp_data = dd; + command->comp_func = mtip_async_complete; + command->direction = (dir == READ ? DMA_FROM_DEVICE : DMA_TO_DEVICE); + + /* + * Set the completion function and data for the command passed + * from the upper layer. + */ + command->async_data = data; + command->async_callback = callback; + + /* + * Lock used to prevent this command from being issued + * if an internal command is in progress. + */ + down_read(&port->dd->internal_sem); + + /* Issue the command to the hardware */ + mtip_issue_ncq_command(port, tag); + + /* Set the command's timeout value.*/ + port->commands[tag].comp_time = jiffies + msecs_to_jiffies( + MTIP_NCQ_COMMAND_TIMEOUT_MS); + + up_read(&port->dd->internal_sem); +} + +/* + * Release a command slot. + * + * @dd Pointer to the driver data structure. + * @tag Slot tag + * + * return value + * None + */ +void mtip_hw_release_scatterlist(struct driver_data *dd, int tag) +{ + release_slot(dd->port, tag); +} + +/* + * Obtain a command slot and return its associated scatter list. + * + * @dd Pointer to the driver data structure. + * @tag Pointer to an int that will receive the allocated command + * slot tag. + * + * return value + * Pointer to the scatter list for the allocated command slot + * or NULL if no command slots are available. + */ +struct scatterlist *mtip_hw_get_scatterlist(struct driver_data *dd, + int *tag) +{ + /* + * It is possible that, even with this semaphore, a thread + * may think that no command slots are available. Therefore, we + * need to make an attempt to get_slot(). + */ + down(&dd->port->cmd_slot); + *tag = get_slot(dd->port); + + if (unlikely(*tag < 0)) + return NULL; + + return dd->port->commands[*tag].sg; +} + +/* + * Sysfs register/status dump. + * + * @dev Pointer to the device structure, passed by the kernrel. + * @attr Pointer to the device_attribute structure passed by the kernel. + * @buf Pointer to the char buffer that will receive the stats info. + * + * return value + * The size, in bytes, of the data copied into buf. + */ +static ssize_t hw_show_registers(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + u32 group_allocated; + struct driver_data *dd = dev_to_disk(dev)->private_data; + int size = 0; + int n; + + size += sprintf(&buf[size], "%s:\ns_active:\n", __func__); + + for (n = 0; n < dd->slot_groups; n++) + size += sprintf(&buf[size], "0x%08x\n", + readl(dd->port->s_active[n])); + + size += sprintf(&buf[size], "Command Issue:\n"); + + for (n = 0; n < dd->slot_groups; n++) + size += sprintf(&buf[size], "0x%08x\n", + readl(dd->port->cmd_issue[n])); + + size += sprintf(&buf[size], "Allocated:\n"); + + for (n = 0; n < dd->slot_groups; n++) { + if (sizeof(long) > sizeof(u32)) + group_allocated = + dd->port->allocated[n/2] >> (32*(n&1)); + else + group_allocated = dd->port->allocated[n]; + size += sprintf(&buf[size], "0x%08x\n", + group_allocated); + } + + size += sprintf(&buf[size], "completed:\n"); + + for (n = 0; n < dd->slot_groups; n++) + size += sprintf(&buf[size], "0x%08x\n", + readl(dd->port->completed[n])); + + size += sprintf(&buf[size], "PORT_IRQ_STAT 0x%08x\n", + readl(dd->port->mmio + PORT_IRQ_STAT)); + size += sprintf(&buf[size], "HOST_IRQ_STAT 0x%08x\n", + readl(dd->mmio + HOST_IRQ_STAT)); + + return size; +} +static DEVICE_ATTR(registers, S_IRUGO, hw_show_registers, NULL); + +/* + * Create the sysfs related attributes. + * + * @dd Pointer to the driver data structure. + * @kobj Pointer to the kobj for the block device. + * + * return value + * 0 Operation completed successfully. + * -EINVAL Invalid parameter. + */ +int mtip_hw_sysfs_init(struct driver_data *dd, struct kobject *kobj) +{ + if (!kobj || !dd) + return -EINVAL; + + if (sysfs_create_file(kobj, &dev_attr_registers.attr)) + dev_warn(&dd->pdev->dev, + "Error creating registers sysfs entry\n"); + return 0; +} + +/* + * Remove the sysfs related attributes. + * + * @dd Pointer to the driver data structure. + * @kobj Pointer to the kobj for the block device. + * + * return value + * 0 Operation completed successfully. + * -EINVAL Invalid parameter. + */ +int mtip_hw_sysfs_exit(struct driver_data *dd, struct kobject *kobj) +{ + if (!kobj || !dd) + return -EINVAL; + + sysfs_remove_file(kobj, &dev_attr_registers.attr); + + return 0; +} + +/* + * Perform any init/resume time hardware setup + * + * @dd Pointer to the driver data structure. + * + * return value + * None + */ +static inline void hba_setup(struct driver_data *dd) +{ + u32 hwdata; + hwdata = readl(dd->mmio + HOST_HSORG); + + /* interrupt bug workaround: use only 1 IS bit.*/ + writel(hwdata | + HSORG_DISABLE_SLOTGRP_INTR | + HSORG_DISABLE_SLOTGRP_PXIS, + dd->mmio + HOST_HSORG); +} + +/* + * Detect the details of the product, and store anything needed + * into the driver data structure. This includes product type and + * version and number of slot groups. + * + * @dd Pointer to the driver data structure. + * + * return value + * None + */ +static void mtip_detect_product(struct driver_data *dd) +{ + u32 hwdata; + unsigned int rev, slotgroups; + + /* + * HBA base + 0xFC [15:0] - vendor-specific hardware interface + * info register: + * [15:8] hardware/software interface rev# + * [ 3] asic-style interface + * [ 2:0] number of slot groups, minus 1 (only valid for asic-style). + */ + hwdata = readl(dd->mmio + HOST_HSORG); + + dd->product_type = MTIP_PRODUCT_UNKNOWN; + dd->slot_groups = 1; + + if (hwdata & 0x8) { + dd->product_type = MTIP_PRODUCT_ASICFPGA; + rev = (hwdata & HSORG_HWREV) >> 8; + slotgroups = (hwdata & HSORG_SLOTGROUPS) + 1; + dev_info(&dd->pdev->dev, + "ASIC-FPGA design, HS rev 0x%x, " + "%i slot groups [%i slots]\n", + rev, + slotgroups, + slotgroups * 32); + + if (slotgroups > MTIP_MAX_SLOT_GROUPS) { + dev_warn(&dd->pdev->dev, + "Warning: driver only supports " + "%i slot groups.\n", MTIP_MAX_SLOT_GROUPS); + slotgroups = MTIP_MAX_SLOT_GROUPS; + } + dd->slot_groups = slotgroups; + return; + } + + dev_warn(&dd->pdev->dev, "Unrecognized product id\n"); +} + +/* + * Blocking wait for FTL rebuild to complete + * + * @dd Pointer to the DRIVER_DATA structure. + * + * return value + * 0 FTL rebuild completed successfully + * -EFAULT FTL rebuild error/timeout/interruption + */ +static int mtip_ftl_rebuild_poll(struct driver_data *dd) +{ + unsigned long timeout, cnt = 0, start; + + dev_warn(&dd->pdev->dev, + "FTL rebuild in progress. Polling for completion.\n"); + + start = jiffies; + dd->ftlrebuildflag = 1; + timeout = jiffies + msecs_to_jiffies(MTIP_FTL_REBUILD_TIMEOUT_MS); + + do { +#ifdef CONFIG_HOTPLUG + if (mtip_check_surprise_removal(dd->pdev)) + return -EFAULT; +#endif + if (mtip_get_identify(dd->port, NULL) < 0) + return -EFAULT; + + if (*(dd->port->identify + MTIP_FTL_REBUILD_OFFSET) == + MTIP_FTL_REBUILD_MAGIC) { + ssleep(1); + /* Print message every 3 minutes */ + if (cnt++ >= 180) { + dev_warn(&dd->pdev->dev, + "FTL rebuild in progress (%d secs).\n", + jiffies_to_msecs(jiffies - start) / 1000); + cnt = 0; + } + } else { + dev_warn(&dd->pdev->dev, + "FTL rebuild complete (%d secs).\n", + jiffies_to_msecs(jiffies - start) / 1000); + dd->ftlrebuildflag = 0; + break; + } + ssleep(10); + } while (time_before(jiffies, timeout)); + + /* Check for timeout */ + if (dd->ftlrebuildflag) { + dev_err(&dd->pdev->dev, + "Timed out waiting for FTL rebuild to complete (%d secs).\n", + jiffies_to_msecs(jiffies - start) / 1000); + return -EFAULT; + } + + return 0; +} + +/* + * Called once for each card. + * + * @dd Pointer to the driver data structure. + * + * return value + * 0 on success, else an error code. + */ +int mtip_hw_init(struct driver_data *dd) +{ + int i; + int rv; + unsigned int num_command_slots; + + dd->mmio = pcim_iomap_table(dd->pdev)[MTIP_ABAR]; + + mtip_detect_product(dd); + if (dd->product_type == MTIP_PRODUCT_UNKNOWN) { + rv = -EIO; + goto out1; + } + num_command_slots = dd->slot_groups * 32; + + hba_setup(dd); + + /* + * Initialize the internal semaphore + * Use a rw semaphore to enable prioritization of + * mgmnt ioctl traffic during heavy IO load + */ + init_rwsem(&dd->internal_sem); + + tasklet_init(&dd->tasklet, mtip_tasklet, (unsigned long)dd); + + dd->port = kzalloc(sizeof(struct mtip_port), GFP_KERNEL); + if (!dd->port) { + dev_err(&dd->pdev->dev, + "Memory allocation: port structure\n"); + return -ENOMEM; + } + + /* Counting semaphore to track command slot usage */ + sema_init(&dd->port->cmd_slot, num_command_slots - 1); + + /* Spinlock to prevent concurrent issue */ + spin_lock_init(&dd->port->cmd_issue_lock); + + /* Set the port mmio base address. */ + dd->port->mmio = dd->mmio + PORT_OFFSET; + dd->port->dd = dd; + + /* Allocate memory for the command list. */ + dd->port->command_list = + dmam_alloc_coherent(&dd->pdev->dev, + HW_PORT_PRIV_DMA_SZ + (ATA_SECT_SIZE * 2), + &dd->port->command_list_dma, + GFP_KERNEL); + if (!dd->port->command_list) { + dev_err(&dd->pdev->dev, + "Memory allocation: command list\n"); + rv = -ENOMEM; + goto out1; + } + + /* Clear the memory we have allocated. */ + memset(dd->port->command_list, + 0, + HW_PORT_PRIV_DMA_SZ + (ATA_SECT_SIZE * 2)); + + /* Setup the addresse of the RX FIS. */ + dd->port->rxfis = dd->port->command_list + HW_CMD_SLOT_SZ; + dd->port->rxfis_dma = dd->port->command_list_dma + HW_CMD_SLOT_SZ; + + /* Setup the address of the command tables. */ + dd->port->command_table = dd->port->rxfis + AHCI_RX_FIS_SZ; + dd->port->command_tbl_dma = dd->port->rxfis_dma + AHCI_RX_FIS_SZ; + + /* Setup the address of the identify data. */ + dd->port->identify = dd->port->command_table + + HW_CMD_TBL_AR_SZ; + dd->port->identify_dma = dd->port->command_tbl_dma + + HW_CMD_TBL_AR_SZ; + + /* Setup the address of the sector buffer. */ + dd->port->sector_buffer = (void *) dd->port->identify + ATA_SECT_SIZE; + dd->port->sector_buffer_dma = dd->port->identify_dma + ATA_SECT_SIZE; + + /* Point the command headers at the command tables. */ + for (i = 0; i < num_command_slots; i++) { + dd->port->commands[i].command_header = + dd->port->command_list + + (sizeof(struct mtip_cmd_hdr) * i); + dd->port->commands[i].command_header_dma = + dd->port->command_list_dma + + (sizeof(struct mtip_cmd_hdr) * i); + + dd->port->commands[i].command = + dd->port->command_table + (HW_CMD_TBL_SZ * i); + dd->port->commands[i].command_dma = + dd->port->command_tbl_dma + (HW_CMD_TBL_SZ * i); + + if (readl(dd->mmio + HOST_CAP) & HOST_CAP_64) + dd->port->commands[i].command_header->ctbau = + cpu_to_le32( + (dd->port->commands[i].command_dma >> 16) >> 16); + dd->port->commands[i].command_header->ctba = cpu_to_le32( + dd->port->commands[i].command_dma & 0xffffffff); + + /* + * If this is not done, a bug is reported by the stock + * FC11 i386. Due to the fact that it has lots of kernel + * debugging enabled. + */ + sg_init_table(dd->port->commands[i].sg, MTIP_MAX_SG); + + /* Mark all commands as currently inactive.*/ + atomic_set(&dd->port->commands[i].active, 0); + } + + /* Setup the pointers to the extended s_active and CI registers. */ + for (i = 0; i < dd->slot_groups; i++) { + dd->port->s_active[i] = + dd->port->mmio + i*0x80 + PORT_SCR_ACT; + dd->port->cmd_issue[i] = + dd->port->mmio + i*0x80 + PORT_COMMAND_ISSUE; + dd->port->completed[i] = + dd->port->mmio + i*0x80 + PORT_SDBV; + } + + /* Reset the HBA. */ + if (mtip_hba_reset(dd) < 0) { + dev_err(&dd->pdev->dev, + "Card did not reset within timeout\n"); + rv = -EIO; + goto out2; + } + + mtip_init_port(dd->port); + mtip_start_port(dd->port); + + /* Setup the ISR and enable interrupts. */ + rv = devm_request_irq(&dd->pdev->dev, + dd->pdev->irq, + mtip_irq_handler, + IRQF_SHARED, + dev_driver_string(&dd->pdev->dev), + dd); + + if (rv) { + dev_err(&dd->pdev->dev, + "Unable to allocate IRQ %d\n", dd->pdev->irq); + goto out2; + } + + /* Enable interrupts on the HBA. */ + writel(readl(dd->mmio + HOST_CTL) | HOST_IRQ_EN, + dd->mmio + HOST_CTL); + + init_timer(&dd->port->cmd_timer); + dd->port->cmd_timer.data = (unsigned long int) dd->port; + dd->port->cmd_timer.function = mtip_timeout_function; + mod_timer(&dd->port->cmd_timer, + jiffies + msecs_to_jiffies(MTIP_TIMEOUT_CHECK_PERIOD)); + + if (mtip_get_identify(dd->port, NULL) < 0) { + rv = -EFAULT; + goto out3; + } + mtip_dump_identify(dd->port); + + if (*(dd->port->identify + MTIP_FTL_REBUILD_OFFSET) == + MTIP_FTL_REBUILD_MAGIC) { + return mtip_ftl_rebuild_poll(dd); + } + return rv; + +out3: + del_timer_sync(&dd->port->cmd_timer); + + /* Disable interrupts on the HBA. */ + writel(readl(dd->mmio + HOST_CTL) & ~HOST_IRQ_EN, + dd->mmio + HOST_CTL); + + /*Release the IRQ. */ + devm_free_irq(&dd->pdev->dev, dd->pdev->irq, dd); + +out2: + mtip_deinit_port(dd->port); + + /* Free the command/command header memory. */ + dmam_free_coherent(&dd->pdev->dev, + HW_PORT_PRIV_DMA_SZ + (ATA_SECT_SIZE * 2), + dd->port->command_list, + dd->port->command_list_dma); +out1: + /* Free the memory allocated for the for structure. */ + kfree(dd->port); + + return rv; +} + +/* + * Called to deinitialize an interface. + * + * @dd Pointer to the driver data structure. + * + * return value + * 0 + */ +int mtip_hw_exit(struct driver_data *dd) +{ + /* + * Send standby immediate (E0h) to the drive so that it + * saves its state. + */ + if (atomic_read(&dd->drv_cleanup_done) != true) { + + mtip_standby_immediate(dd->port); + + /* de-initialize the port. */ + mtip_deinit_port(dd->port); + + /* Disable interrupts on the HBA. */ + writel(readl(dd->mmio + HOST_CTL) & ~HOST_IRQ_EN, + dd->mmio + HOST_CTL); + } + + del_timer_sync(&dd->port->cmd_timer); + + /* Stop the bottom half tasklet. */ + tasklet_kill(&dd->tasklet); + + /* Release the IRQ. */ + devm_free_irq(&dd->pdev->dev, dd->pdev->irq, dd); + + /* Free the command/command header memory. */ + dmam_free_coherent(&dd->pdev->dev, + HW_PORT_PRIV_DMA_SZ + (ATA_SECT_SIZE * 2), + dd->port->command_list, + dd->port->command_list_dma); + /* Free the memory allocated for the for structure. */ + kfree(dd->port); + + return 0; +} + +/* + * Issue a Standby Immediate command to the device. + * + * This function is called by the Block Layer just before the + * system powers off during a shutdown. + * + * @dd Pointer to the driver data structure. + * + * return value + * 0 + */ +int mtip_hw_shutdown(struct driver_data *dd) +{ + /* + * Send standby immediate (E0h) to the drive so that it + * saves its state. + */ + mtip_standby_immediate(dd->port); + + return 0; +} + +/* + * Suspend function + * + * This function is called by the Block Layer just before the + * system hibernates. + * + * @dd Pointer to the driver data structure. + * + * return value + * 0 Suspend was successful + * -EFAULT Suspend was not successful + */ +int mtip_hw_suspend(struct driver_data *dd) +{ + /* + * Send standby immediate (E0h) to the drive + * so that it saves its state. + */ + if (mtip_standby_immediate(dd->port) != 0) { + dev_err(&dd->pdev->dev, + "Failed standby-immediate command\n"); + return -EFAULT; + } + + /* Disable interrupts on the HBA.*/ + writel(readl(dd->mmio + HOST_CTL) & ~HOST_IRQ_EN, + dd->mmio + HOST_CTL); + mtip_deinit_port(dd->port); + + return 0; +} + +/* + * Resume function + * + * This function is called by the Block Layer as the + * system resumes. + * + * @dd Pointer to the driver data structure. + * + * return value + * 0 Resume was successful + * -EFAULT Resume was not successful + */ +int mtip_hw_resume(struct driver_data *dd) +{ + /* Perform any needed hardware setup steps */ + hba_setup(dd); + + /* Reset the HBA */ + if (mtip_hba_reset(dd) != 0) { + dev_err(&dd->pdev->dev, + "Unable to reset the HBA\n"); + return -EFAULT; + } + + /* + * Enable the port, DMA engine, and FIS reception specific + * h/w in controller. + */ + mtip_init_port(dd->port); + mtip_start_port(dd->port); + + /* Enable interrupts on the HBA.*/ + writel(readl(dd->mmio + HOST_CTL) | HOST_IRQ_EN, + dd->mmio + HOST_CTL); + + return 0; +} + +/* + * This function is called for clean the pending command in the + * command slot during the surprise removal of device and return + * error to the upper layer. + * + * @dd Pointer to the DRIVER_DATA structure. + * + * return value + * None + */ +void mtip_command_cleanup(struct driver_data *dd) +{ + int group = 0, commandslot = 0, commandindex = 0; + struct mtip_cmd *command; + struct mtip_port *port = dd->port; + + for (group = 0; group < 4; group++) { + for (commandslot = 0; commandslot < 32; commandslot++) { + if (!(port->allocated[group] & (1 << commandslot))) + continue; + + commandindex = group << 5 | commandslot; + command = &port->commands[commandindex]; + + if (atomic_read(&command->active) + && (command->async_callback)) { + command->async_callback(command->async_data, + -ENODEV); + command->async_callback = NULL; + command->async_data = NULL; + } + + dma_unmap_sg(&port->dd->pdev->dev, + command->sg, + command->scatter_ents, + command->direction); + } + } + + up(&port->cmd_slot); + + atomic_set(&dd->drv_cleanup_done, true); +} + +/* + * Helper function for reusing disk name + * upon hot insertion. + */ +static int rssd_disk_name_format(char *prefix, + int index, + char *buf, + int buflen) +{ + const int base = 'z' - 'a' + 1; + char *begin = buf + strlen(prefix); + char *end = buf + buflen; + char *p; + int unit; + + p = end - 1; + *p = '\0'; + unit = base; + do { + if (p == begin) + return -EINVAL; + *--p = 'a' + (index % unit); + index = (index / unit) - 1; + } while (index >= 0); + + memmove(begin, p, end - p); + memcpy(buf, prefix, strlen(prefix)); + + return 0; +} + +/* + * Block layer IOCTL handler. + * + * @dev Pointer to the block_device structure. + * @mode ignored + * @cmd IOCTL command passed from the user application. + * @arg Argument passed from the user application. + * + * return value + * 0 IOCTL completed successfully. + * -ENOTTY IOCTL not supported or invalid driver data + * structure pointer. + */ +static int mtip_block_ioctl(struct block_device *dev, + fmode_t mode, + unsigned cmd, + unsigned long arg) +{ + struct driver_data *dd = dev->bd_disk->private_data; + + if (!capable(CAP_SYS_ADMIN)) + return -EACCES; + + if (!dd) + return -ENOTTY; + + switch (cmd) { + case BLKFLSBUF: + return 0; + default: + return mtip_hw_ioctl(dd, cmd, arg, 0); + } +} + +/* + * Block layer compat IOCTL handler. + * + * @dev Pointer to the block_device structure. + * @mode ignored + * @cmd IOCTL command passed from the user application. + * @arg Argument passed from the user application. + * + * return value + * 0 IOCTL completed successfully. + * -ENOTTY IOCTL not supported or invalid driver data + * structure pointer. + */ +static int mtip_block_compat_ioctl(struct block_device *dev, + fmode_t mode, + unsigned cmd, + unsigned long arg) +{ + struct driver_data *dd = dev->bd_disk->private_data; + + if (!capable(CAP_SYS_ADMIN)) + return -EACCES; + + if (!dd) + return -ENOTTY; + + switch (cmd) { + case BLKFLSBUF: + return 0; + default: + return mtip_hw_ioctl(dd, cmd, arg, 1); + } +} + +/* + * Obtain the geometry of the device. + * + * You may think that this function is obsolete, but some applications, + * fdisk for example still used CHS values. This function describes the + * device as having 224 heads and 56 sectors per cylinder. These values are + * chosen so that each cylinder is aligned on a 4KB boundary. Since a + * partition is described in terms of a start and end cylinder this means + * that each partition is also 4KB aligned. Non-aligned partitions adversely + * affects performance. + * + * @dev Pointer to the block_device strucutre. + * @geo Pointer to a hd_geometry structure. + * + * return value + * 0 Operation completed successfully. + * -ENOTTY An error occurred while reading the drive capacity. + */ +static int mtip_block_getgeo(struct block_device *dev, + struct hd_geometry *geo) +{ + struct driver_data *dd = dev->bd_disk->private_data; + sector_t capacity; + + if (!dd) + return -ENOTTY; + + if (!(mtip_hw_get_capacity(dd, &capacity))) { + dev_warn(&dd->pdev->dev, + "Could not get drive capacity.\n"); + return -ENOTTY; + } + + geo->heads = 224; + geo->sectors = 56; +#if BITS_PER_LONG == 64 + geo->cylinders = capacity / (geo->heads * geo->sectors); +#else + do_div(capacity, (geo->heads * geo->sectors)); + geo->cylinders = capacity; +#endif + return 0; +} + +/* + * Block device operation function. + * + * This structure contains pointers to the functions required by the block + * layer. + */ +static const struct block_device_operations mtip_block_ops = { + .ioctl = mtip_block_ioctl, + .compat_ioctl = mtip_block_compat_ioctl, + .getgeo = mtip_block_getgeo, + .owner = THIS_MODULE +}; + +/* + * Block layer make request function. + * + * This function is called by the kernel to process a BIO for + * the P320 device. + * + * @queue Pointer to the request queue. Unused other than to obtain + * the driver data structure. + * @bio Pointer to the BIO. + * + * return value + * 0 + */ +static int mtip_make_request(struct request_queue *queue, struct bio *bio) +{ + struct driver_data *dd = queue->queuedata; + struct scatterlist *sg; + struct bio_vec *bvec; + int nents = 0; + int tag = 0; + + if (unlikely(!bio_has_data(bio))) { + blk_queue_flush(queue, 0); + bio_endio(bio, 0); + return 0; + } + + if (unlikely(atomic_read(&dd->eh_active))) { + bio_endio(bio, -EBUSY); + return 0; + } + + sg = mtip_hw_get_scatterlist(dd, &tag); + if (likely(sg != NULL)) { + blk_queue_bounce(queue, &bio); + + if (unlikely((bio)->bi_vcnt > MTIP_MAX_SG)) { + dev_warn(&dd->pdev->dev, + "Maximum number of SGL entries exceeded"); + bio_io_error(bio); + mtip_hw_release_scatterlist(dd, tag); + return 0; + } + + /* Create the scatter list for this bio. */ + bio_for_each_segment(bvec, bio, nents) { + sg_set_page(&sg[nents], + bvec->bv_page, + bvec->bv_len, + bvec->bv_offset); + } + + /* Issue the read/write. */ + mtip_hw_submit_io(dd, + bio->bi_sector, + bio_sectors(bio), + nents, + tag, + bio_endio, + bio, + bio->bi_rw & REQ_FLUSH, + bio_data_dir(bio)); + } else { + bio_io_error(bio); + } + + return 0; +} + +/* + * Block layer initialization function. + * + * This function is called once by the PCI layer for each P320 + * device that is connected to the system. + * + * @dd Pointer to the driver data structure. + * + * return value + * 0 on success else an error code. + */ +int mtip_block_initialize(struct driver_data *dd) +{ + int rv = 0; + sector_t capacity; + unsigned int index = 0; + struct kobject *kobj; + + /* Initialize the protocol layer. */ + rv = mtip_hw_init(dd); + if (rv < 0) { + dev_err(&dd->pdev->dev, + "Protocol layer initialization failed\n"); + rv = -EINVAL; + goto protocol_init_error; + } + + /* Allocate the request queue. */ + dd->queue = blk_alloc_queue(GFP_KERNEL); + if (dd->queue == NULL) { + dev_err(&dd->pdev->dev, + "Unable to allocate request queue\n"); + rv = -ENOMEM; + goto block_queue_alloc_init_error; + } + + /* Attach our request function to the request queue. */ + blk_queue_make_request(dd->queue, mtip_make_request); + + /* Set device limits. */ + set_bit(QUEUE_FLAG_NONROT, &dd->queue->queue_flags); + blk_queue_max_segments(dd->queue, MTIP_MAX_SG); + blk_queue_physical_block_size(dd->queue, 4096); + blk_queue_io_min(dd->queue, 4096); + + dd->disk = alloc_disk(MTIP_MAX_MINORS); + if (dd->disk == NULL) { + dev_err(&dd->pdev->dev, + "Unable to allocate gendisk structure\n"); + rv = -EINVAL; + goto alloc_disk_error; + } + + /* Generate the disk name, implemented same as in sd.c */ + do { + if (!ida_pre_get(&rssd_index_ida, GFP_KERNEL)) + goto ida_get_error; + + spin_lock(&rssd_index_lock); + rv = ida_get_new(&rssd_index_ida, &index); + spin_unlock(&rssd_index_lock); + } while (rv == -EAGAIN); + + if (rv) + goto ida_get_error; + + rv = rssd_disk_name_format("rssd", + index, + dd->disk->disk_name, + DISK_NAME_LEN); + if (rv) + goto disk_index_error; + + dd->disk->driverfs_dev = &dd->pdev->dev; + dd->disk->major = dd->major; + dd->disk->first_minor = dd->instance * MTIP_MAX_MINORS; + dd->disk->fops = &mtip_block_ops; + dd->disk->queue = dd->queue; + dd->disk->private_data = dd; + dd->queue->queuedata = dd; + dd->index = index; + + /* Set the capacity of the device in 512 byte sectors. */ + if (!(mtip_hw_get_capacity(dd, &capacity))) { + dev_warn(&dd->pdev->dev, + "Could not read drive capacity\n"); + rv = -EIO; + goto read_capacity_error; + } + set_capacity(dd->disk, capacity); + + /* Enable the block device and add it to /dev */ + add_disk(dd->disk); + + /* + * Now that the disk is active, initialize any sysfs attributes + * managed by the protocol layer. + */ + kobj = kobject_get(&disk_to_dev(dd->disk)->kobj); + if (kobj) { + mtip_hw_sysfs_init(dd, kobj); + kobject_put(kobj); + } + + return rv; + +read_capacity_error: + /* + * Delete our gendisk structure. This also removes the device + * from /dev + */ + del_gendisk(dd->disk); + +disk_index_error: + spin_lock(&rssd_index_lock); + ida_remove(&rssd_index_ida, index); + spin_unlock(&rssd_index_lock); + +ida_get_error: + put_disk(dd->disk); + +alloc_disk_error: + blk_cleanup_queue(dd->queue); + +block_queue_alloc_init_error: + /* De-initialize the protocol layer. */ + mtip_hw_exit(dd); + +protocol_init_error: + return rv; +} + +/* + * Block layer deinitialization function. + * + * Called by the PCI layer as each P320 device is removed. + * + * @dd Pointer to the driver data structure. + * + * return value + * 0 + */ +int mtip_block_remove(struct driver_data *dd) +{ + struct kobject *kobj; + /* Clean up the sysfs attributes managed by the protocol layer. */ + kobj = kobject_get(&disk_to_dev(dd->disk)->kobj); + if (kobj) { + mtip_hw_sysfs_exit(dd, kobj); + kobject_put(kobj); + } + + /* + * Delete our gendisk structure. This also removes the device + * from /dev + */ + del_gendisk(dd->disk); + blk_cleanup_queue(dd->queue); + dd->disk = NULL; + dd->queue = NULL; + + /* De-initialize the protocol layer. */ + mtip_hw_exit(dd); + + return 0; +} + +/* + * Function called by the PCI layer when just before the + * machine shuts down. + * + * If a protocol layer shutdown function is present it will be called + * by this function. + * + * @dd Pointer to the driver data structure. + * + * return value + * 0 + */ +int mtip_block_shutdown(struct driver_data *dd) +{ + dev_info(&dd->pdev->dev, + "Shutting down %s ...\n", dd->disk->disk_name); + + /* Delete our gendisk structure, and cleanup the blk queue. */ + del_gendisk(dd->disk); + blk_cleanup_queue(dd->queue); + dd->disk = NULL; + dd->queue = NULL; + + mtip_hw_shutdown(dd); + return 0; +} + +int mtip_block_suspend(struct driver_data *dd) +{ + dev_info(&dd->pdev->dev, + "Suspending %s ...\n", dd->disk->disk_name); + mtip_hw_suspend(dd); + return 0; +} + +int mtip_block_resume(struct driver_data *dd) +{ + dev_info(&dd->pdev->dev, "Resuming %s ...\n", + dd->disk->disk_name); + mtip_hw_resume(dd); + return 0; +} + +/* + * Called for each supported PCI device detected. + * + * This function allocates the private data structure, enables the + * PCI device and then calls the block layer initialization function. + * + * return value + * 0 on success else an error code. + */ +static int mtip_pci_probe(struct pci_dev *pdev, + const struct pci_device_id *ent) +{ + int rv = 0; + struct driver_data *dd = NULL; + + /* Allocate memory for this devices private data. */ + dd = kzalloc(sizeof(struct driver_data), GFP_KERNEL); + if (dd == NULL) { + dev_err(&pdev->dev, + "Unable to allocate memory for driver data\n"); + return -ENOMEM; + } + + /* Set the atomic variable as 1 in case of SRSI */ + atomic_set(&dd->drv_cleanup_done, true); + + atomic_set(&dd->resumeflag, false); + atomic_set(&dd->eh_active, 0); + + /* Attach the private data to this PCI device. */ + pci_set_drvdata(pdev, dd); + + rv = pcim_enable_device(pdev); + if (rv < 0) { + dev_err(&pdev->dev, "Unable to enable device\n"); + goto iomap_err; + } + + /* Map BAR5 to memory. */ + rv = pcim_iomap_regions(pdev, 1 << MTIP_ABAR, MTIP_DRV_NAME); + if (rv < 0) { + dev_err(&pdev->dev, "Unable to map regions\n"); + goto iomap_err; + } + + if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) { + rv = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64)); + + if (rv) { + rv = pci_set_consistent_dma_mask(pdev, + DMA_BIT_MASK(32)); + if (rv) { + dev_warn(&pdev->dev, + "64-bit DMA enable failed\n"); + goto setmask_err; + } + } + } + + pci_set_master(pdev); + + if (pci_enable_msi(pdev)) { + dev_warn(&pdev->dev, + "Unable to enable MSI interrupt.\n"); + goto block_initialize_err; + } + + /* Copy the info we may need later into the private data structure. */ + dd->major = mtip_major; + dd->protocol = ent->driver_data; + dd->instance = instance; + dd->pdev = pdev; + + /* Initialize the block layer. */ + rv = mtip_block_initialize(dd); + if (rv < 0) { + dev_err(&pdev->dev, + "Unable to initialize block layer\n"); + goto block_initialize_err; + } + + /* + * Increment the instance count so that each device has a unique + * instance number. + */ + instance++; + + goto done; + +block_initialize_err: + pci_disable_msi(pdev); + +setmask_err: + pcim_iounmap_regions(pdev, 1 << MTIP_ABAR); + +iomap_err: + kfree(dd); + pci_set_drvdata(pdev, NULL); + return rv; +done: + /* Set the atomic variable as 0 in case of SRSI */ + atomic_set(&dd->drv_cleanup_done, true); + + return rv; +} + +/* + * Called for each probed device when the device is removed or the + * driver is unloaded. + * + * return value + * None + */ +static void mtip_pci_remove(struct pci_dev *pdev) +{ + struct driver_data *dd = pci_get_drvdata(pdev); + int counter = 0; + + if (mtip_check_surprise_removal(pdev)) { + while (atomic_read(&dd->drv_cleanup_done) == false) { + counter++; + msleep(20); + if (counter == 10) { + /* Cleanup the outstanding commands */ + mtip_command_cleanup(dd); + break; + } + } + } + /* Set the atomic variable as 1 in case of SRSI */ + atomic_set(&dd->drv_cleanup_done, true); + + /* Clean up the block layer. */ + mtip_block_remove(dd); + + pci_disable_msi(pdev); + + kfree(dd); + pcim_iounmap_regions(pdev, 1 << MTIP_ABAR); +} + +/* + * Called for each probed device when the device is suspended. + * + * return value + * 0 Success + * <0 Error + */ +static int mtip_pci_suspend(struct pci_dev *pdev, pm_message_t mesg) +{ + int rv = 0; + struct driver_data *dd = pci_get_drvdata(pdev); + + if (!dd) { + dev_err(&pdev->dev, + "Driver private datastructure is NULL\n"); + return -EFAULT; + } + + atomic_set(&dd->resumeflag, true); + + /* Disable ports & interrupts then send standby immediate */ + rv = mtip_block_suspend(dd); + if (rv < 0) { + dev_err(&pdev->dev, + "Failed to suspend controller\n"); + return rv; + } + + /* + * Save the pci config space to pdev structure & + * disable the device + */ + pci_save_state(pdev); + pci_disable_device(pdev); + + /* Move to Low power state*/ + pci_set_power_state(pdev, PCI_D3hot); + + return rv; +} + +/* + * Called for each probed device when the device is resumed. + * + * return value + * 0 Success + * <0 Error + */ +static int mtip_pci_resume(struct pci_dev *pdev) +{ + int rv = 0; + struct driver_data *dd; + + dd = pci_get_drvdata(pdev); + if (!dd) { + dev_err(&pdev->dev, + "Driver private datastructure is NULL\n"); + return -EFAULT; + } + + /* Move the device to active State */ + pci_set_power_state(pdev, PCI_D0); + + /* Restore PCI configuration space */ + pci_restore_state(pdev); + + /* Enable the PCI device*/ + rv = pcim_enable_device(pdev); + if (rv < 0) { + dev_err(&pdev->dev, + "Failed to enable card during resume\n"); + goto err; + } + pci_set_master(pdev); + + /* + * Calls hbaReset, initPort, & startPort function + * then enables interrupts + */ + rv = mtip_block_resume(dd); + if (rv < 0) + dev_err(&pdev->dev, "Unable to resume\n"); + +err: + atomic_set(&dd->resumeflag, false); + + return rv; +} + +/* + * Shutdown routine + * + * return value + * None + */ +static void mtip_pci_shutdown(struct pci_dev *pdev) +{ + struct driver_data *dd = pci_get_drvdata(pdev); + if (dd) + mtip_block_shutdown(dd); +} + +/* + * This function check_for_surprise_removal is called + * while card is removed from the system and it will + * read the vendor id from the configration space + * + * @pdev Pointer to the pci_dev structure. + * + * return value + * true if device removed, else false + */ +bool mtip_check_surprise_removal(struct pci_dev *pdev) +{ + u16 vendor_id = 0; + + /* Read the vendorID from the configuration space */ + pci_read_config_word(pdev, 0x00, &vendor_id); + if (vendor_id == 0xFFFF) + return true; /* device removed */ + + return false; /* device present */ +} + +/* Table of device ids supported by this driver. */ +static DEFINE_PCI_DEVICE_TABLE(mtip_pci_tbl) = { + { PCI_DEVICE(PCI_VENDOR_ID_MICRON, P320_DEVICE_ID) }, + { 0 } +}; + +/* Structure that describes the PCI driver functions. */ +struct pci_driver mtip_pci_driver = { + .name = MTIP_DRV_NAME, + .id_table = mtip_pci_tbl, + .probe = mtip_pci_probe, + .remove = mtip_pci_remove, + .suspend = mtip_pci_suspend, + .resume = mtip_pci_resume, + .shutdown = mtip_pci_shutdown, +}; + +MODULE_DEVICE_TABLE(pci, mtip_pci_tbl); + +/* + * Module initialization function. + * + * Called once when the module is loaded. This function allocates a major + * block device number to the Cyclone devices and registers the PCI layer + * of the driver. + * + * Return value + * 0 on success else error code. + */ +static int __init mtip_init(void) +{ + printk(KERN_INFO MTIP_DRV_NAME " Version " MTIP_DRV_VERSION "\n"); + + /* Allocate a major block device number to use with this driver. */ + mtip_major = register_blkdev(0, MTIP_DRV_NAME); + if (mtip_major < 0) { + printk(KERN_ERR "Unable to register block device (%d)\n", + mtip_major); + return -EBUSY; + } + + /* Register our PCI operations. */ + return pci_register_driver(&mtip_pci_driver); +} + +/* + * Module de-initialization function. + * + * Called once when the module is unloaded. This function deallocates + * the major block device number allocated by mtip_init() and + * unregisters the PCI layer of the driver. + * + * Return value + * none + */ +static void __exit mtip_exit(void) +{ + /* Release the allocated major block device number. */ + unregister_blkdev(mtip_major, MTIP_DRV_NAME); + + /* Unregister the PCI driver. */ + pci_unregister_driver(&mtip_pci_driver); +} + +MODULE_AUTHOR("Micron Technology, Inc"); +MODULE_DESCRIPTION("Micron RealSSD PCIe Block Driver"); +MODULE_LICENSE("GPL"); +MODULE_VERSION(MTIP_DRV_VERSION); + +module_init(mtip_init); +module_exit(mtip_exit); diff --git a/drivers/block/mtip32xx/mtip32xx.h b/drivers/block/mtip32xx/mtip32xx.h new file mode 100644 index 0000000..3423d18 --- /dev/null +++ b/drivers/block/mtip32xx/mtip32xx.h @@ -0,0 +1,445 @@ +/* + * mtip32xx.h - Header file for the P320 SSD Block Driver + * Copyright (C) 2011 Micron Technology, Inc. + * + * Portions of this code were derived from works subjected to the + * following copyright: + * Copyright (C) 2009 Integrated Device Technology, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef __MTIP32XX_H__ +#define __MTIP32XX_H__ + +#include +#include +#include +#include +#include +#include + +/* Offset of Subsystem Device ID in pci confoguration space */ +#define PCI_SUBSYSTEM_DEVICEID 0x2E + +/* offset of Device Control register in PCIe extended capabilites space */ +#define PCIE_CONFIG_EXT_DEVICE_CONTROL_OFFSET 0x48 + +/* # of times to retry timed out IOs */ +#define MTIP_MAX_RETRIES 5 + +/* Various timeout values in ms */ +#define MTIP_NCQ_COMMAND_TIMEOUT_MS 5000 +#define MTIP_IOCTL_COMMAND_TIMEOUT_MS 5000 +#define MTIP_INTERNAL_COMMAND_TIMEOUT_MS 5000 + +/* check for timeouts every 500ms */ +#define MTIP_TIMEOUT_CHECK_PERIOD 500 + +/* ftl rebuild */ +#define MTIP_FTL_REBUILD_OFFSET 142 +#define MTIP_FTL_REBUILD_MAGIC 0xed51 +#define MTIP_FTL_REBUILD_TIMEOUT_MS 2400000 + +/* Macro to extract the tag bit number from a tag value. */ +#define MTIP_TAG_BIT(tag) (tag & 0x1f) + +/* + * Macro to extract the tag index from a tag value. The index + * is used to access the correct s_active/Command Issue register based + * on the tag value. + */ +#define MTIP_TAG_INDEX(tag) (tag >> 5) + +/* + * Maximum number of scatter gather entries + * a single command may have. + */ +#define MTIP_MAX_SG 128 + +/* + * Maximum number of slot groups (Command Issue & s_active registers) + * NOTE: This is the driver maximum; check dd->slot_groups for actual value. + */ +#define MTIP_MAX_SLOT_GROUPS 8 + +/* Internal command tag. */ +#define MTIP_TAG_INTERNAL 0 + +/* Micron Vendor ID & P320x SSD Device ID */ +#define PCI_VENDOR_ID_MICRON 0x1344 +#define P320_DEVICE_ID 0x5150 + +/* Driver name and version strings */ +#define MTIP_DRV_NAME "mtip32xx" +#define MTIP_DRV_VERSION "1.2.6os2" + +/* Maximum number of minor device numbers per device. */ +#define MTIP_MAX_MINORS 16 + +/* Maximum number of supported command slots. */ +#define MTIP_MAX_COMMAND_SLOTS (MTIP_MAX_SLOT_GROUPS * 32) + +/* + * Per-tag bitfield size in longs. + * Linux bit manipulation functions + * (i.e. test_and_set_bit, find_next_zero_bit) + * manipulate memory in longs, so we try to make the math work. + * take the slot groups and find the number of longs, rounding up. + * Careful! i386 and x86_64 use different size longs! + */ +#define U32_PER_LONG (sizeof(long) / sizeof(u32)) +#define SLOTBITS_IN_LONGS ((MTIP_MAX_SLOT_GROUPS + \ + (U32_PER_LONG-1))/U32_PER_LONG) + +/* BAR number used to access the HBA registers. */ +#define MTIP_ABAR 5 + +/* Forced Unit Access Bit */ +#define FUA_BIT 0x80 + +#ifdef DEBUG + #define dbg_printk(format, arg...) \ + printk(pr_fmt(format), ##arg); +#else + #define dbg_printk(format, arg...) +#endif + +/* Register Frame Information Structure (FIS), host to device. */ +struct host_to_dev_fis { + /* + * FIS type. + * - 27h Register FIS, host to device. + * - 34h Register FIS, device to host. + * - 39h DMA Activate FIS, device to host. + * - 41h DMA Setup FIS, bi-directional. + * - 46h Data FIS, bi-directional. + * - 58h BIST Activate FIS, bi-directional. + * - 5Fh PIO Setup FIS, device to host. + * - A1h Set Device Bits FIS, device to host. + */ + unsigned char type; + unsigned char opts; + unsigned char command; + unsigned char features; + + union { + unsigned char lba_low; + unsigned char sector; + }; + union { + unsigned char lba_mid; + unsigned char cyl_low; + }; + union { + unsigned char lba_hi; + unsigned char cyl_hi; + }; + union { + unsigned char device; + unsigned char head; + }; + + union { + unsigned char lba_low_ex; + unsigned char sector_ex; + }; + union { + unsigned char lba_mid_ex; + unsigned char cyl_low_ex; + }; + union { + unsigned char lba_hi_ex; + unsigned char cyl_hi_ex; + }; + unsigned char features_ex; + + unsigned char sect_count; + unsigned char sect_cnt_ex; + unsigned char res2; + unsigned char control; + + unsigned int res3; +}; + +/* Command header structure. */ +struct mtip_cmd_hdr { + /* + * Command options. + * - Bits 31:16 Number of PRD entries. + * - Bits 15:8 Unused in this implementation. + * - Bit 7 Prefetch bit, informs the drive to prefetch PRD entries. + * - Bit 6 Write bit, should be set when writing data to the device. + * - Bit 5 Unused in this implementation. + * - Bits 4:0 Length of the command FIS in DWords (DWord = 4 bytes). + */ + unsigned int opts; + /* This field is unsed when using NCQ. */ + union { + unsigned int byte_count; + unsigned int status; + }; + /* + * Lower 32 bits of the command table address associated with this + * header. The command table addresses must be 128 byte aligned. + */ + unsigned int ctba; + /* + * If 64 bit addressing is used this field is the upper 32 bits + * of the command table address associated with this command. + */ + unsigned int ctbau; + /* Reserved and unused. */ + unsigned int res[4]; +}; + +/* Command scatter gather structure (PRD). */ +struct mtip_cmd_sg { + /* + * Low 32 bits of the data buffer address. For P320 this + * address must be 8 byte aligned signified by bits 2:0 being + * set to 0. + */ + unsigned int dba; + /* + * When 64 bit addressing is used this field is the upper + * 32 bits of the data buffer address. + */ + unsigned int dba_upper; + /* Unused. */ + unsigned int reserved; + /* + * Bit 31: interrupt when this data block has been transferred. + * Bits 30..22: reserved + * Bits 21..0: byte count (minus 1). For P320 the byte count must be + * 8 byte aligned signified by bits 2:0 being set to 1. + */ + unsigned int info; +}; +struct mtip_port; + +/* Structure used to describe a command. */ +struct mtip_cmd { + + struct mtip_cmd_hdr *command_header; /* ptr to command header entry */ + + dma_addr_t command_header_dma; /* corresponding physical address */ + + void *command; /* ptr to command table entry */ + + dma_addr_t command_dma; /* corresponding physical address */ + + void *comp_data; /* data passed to completion function comp_func() */ + /* + * Completion function called by the ISR upon completion of + * a command. + */ + void (*comp_func)(struct mtip_port *port, + int tag, + void *data, + int status); + /* Additional callback function that may be called by comp_func() */ + void (*async_callback)(void *data, int status); + + void *async_data; /* Addl. data passed to async_callback() */ + + int scatter_ents; /* Number of scatter list entries used */ + + struct scatterlist sg[MTIP_MAX_SG]; /* Scatter list entries */ + + int retries; /* The number of retries left for this command. */ + + int direction; /* Data transfer direction */ + + unsigned long comp_time; /* command completion time, in jiffies */ + + atomic_t active; /* declares if this command sent to the drive. */ +}; + +/* Structure used to describe a port. */ +struct mtip_port { + /* Pointer back to the driver data for this port. */ + struct driver_data *dd; + /* + * Used to determine if the data pointed to by the + * identify field is valid. + */ + unsigned long identify_valid; + /* Base address of the memory mapped IO for the port. */ + void __iomem *mmio; + /* Array of pointers to the memory mapped s_active registers. */ + void __iomem *s_active[MTIP_MAX_SLOT_GROUPS]; + /* Array of pointers to the memory mapped completed registers. */ + void __iomem *completed[MTIP_MAX_SLOT_GROUPS]; + /* Array of pointers to the memory mapped Command Issue registers. */ + void __iomem *cmd_issue[MTIP_MAX_SLOT_GROUPS]; + /* + * Pointer to the beginning of the command header memory as used + * by the driver. + */ + void *command_list; + /* + * Pointer to the beginning of the command header memory as used + * by the DMA. + */ + dma_addr_t command_list_dma; + /* + * Pointer to the beginning of the RX FIS memory as used + * by the driver. + */ + void *rxfis; + /* + * Pointer to the beginning of the RX FIS memory as used + * by the DMA. + */ + dma_addr_t rxfis_dma; + /* + * Pointer to the beginning of the command table memory as used + * by the driver. + */ + void *command_table; + /* + * Pointer to the beginning of the command table memory as used + * by the DMA. + */ + dma_addr_t command_tbl_dma; + /* + * Pointer to the beginning of the identify data memory as used + * by the driver. + */ + u16 *identify; + /* + * Pointer to the beginning of the identify data memory as used + * by the DMA. + */ + dma_addr_t identify_dma; + /* + * Pointer to the beginning of a sector buffer that is used + * by the driver when issuing internal commands. + */ + u16 *sector_buffer; + /* + * Pointer to the beginning of a sector buffer that is used + * by the DMA when the driver issues internal commands. + */ + dma_addr_t sector_buffer_dma; + /* + * Bit significant, used to determine if a command slot has + * been allocated. i.e. the slot is in use. Bits are cleared + * when the command slot and all associated data structures + * are no longer needed. + */ + unsigned long allocated[SLOTBITS_IN_LONGS]; + /* + * Array of command slots. Structure includes pointers to the + * command header and command table, and completion function and data + * pointers. + */ + struct mtip_cmd commands[MTIP_MAX_COMMAND_SLOTS]; + /* Non-zero if an internal command is in progress. */ + int internal_cmd_in_progress; + /* + * Timer used to complete commands that have been active for too long. + */ + struct timer_list cmd_timer; + /* + * Semaphore used to block threads if there are no + * command slots available. + */ + struct semaphore cmd_slot; + /* Spinlock for working around command-issue bug. */ + spinlock_t cmd_issue_lock; +}; + +/* + * Driver private data structure. + * + * One structure is allocated per probed device. + */ +struct driver_data { + void __iomem *mmio; /* Base address of the HBA registers. */ + + int major; /* Major device number. */ + + int instance; /* Instance number. First device probed is 0, ... */ + + int protocol; /* FIXME: Protocol ops array index. */ + + struct gendisk *disk; /* Pointer to our gendisk structure. */ + + struct pci_dev *pdev; /* Pointer to the PCI device structure. */ + + struct request_queue *queue; /* Our request queue. */ + /* + * Semaphore used to lock out read/write commands during the + * execution of an internal command. + */ + struct rw_semaphore internal_sem; + + struct mtip_port *port; /* Pointer to the port data structure. */ + + /* Tasklet used to process the bottom half of the ISR. */ + struct tasklet_struct tasklet; + + unsigned product_type; /* magic value declaring the product type */ + + unsigned slot_groups; /* number of slot groups the product supports */ + + atomic_t drv_cleanup_done; /* Atomic variable for SRSI */ + + unsigned long index; /* Index to determine the disk name */ + + unsigned int ftlrebuildflag; /* FTL rebuild flag */ + + atomic_t resumeflag; /* Atomic variable to track suspend/resume */ + + atomic_t eh_active; /* Flag for error handling tracking */ +}; + +/* Function declarations */ +extern int mtip_block_initialize(struct driver_data *dd); +extern int mtip_block_remove(struct driver_data *dd); +extern int mtip_block_shutdown(struct driver_data *dd); +extern int mtip_block_suspend(struct driver_data *dd); +extern int mtip_block_resume(struct driver_data *dd); +extern int mtip_hw_init(struct driver_data *dd); +extern int mtip_hw_exit(struct driver_data *dd); +extern int mtip_hw_shutdown(struct driver_data *dd); +extern bool mtip_hw_get_capacity(struct driver_data *dd, sector_t *sectors); +extern void mtip_hw_release_scatterlist( + struct driver_data *dd, + int tag); +extern struct scatterlist *mtip_hw_get_scatterlist( + struct driver_data *dd, + int *tag); +extern void mtip_hw_submit_io(struct driver_data *dd, + sector_t start, + int nsect, + int nents, + int tag, + void *callback, + void *data, + int barrier, + int dir); +extern int mtip_hw_ioctl(struct driver_data *dd, + unsigned int cmd, + unsigned long arg, + unsigned char compat); +extern int mtip_hw_sysfs_init(struct driver_data *dd, struct kobject *kobj); +extern int mtip_hw_sysfs_exit(struct driver_data *dd, struct kobject *kobj); +extern int mtip_hw_resume(struct driver_data *dd); +extern int mtip_hw_suspend(struct driver_data *dd); +void mtip_command_cleanup(struct driver_data *dd); +bool mtip_check_surprise_removal(struct pci_dev *pdev); +void mtip_restart_port(struct mtip_port *port); + +#endif -- cgit v0.10.2 From 16d02c040bb6769068f7c4b54ea8542f14237362 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Tue, 27 Sep 2011 15:50:01 -0600 Subject: mtip32xx: fix warnings/errors on 32-bit compiles We need to clean up the compat ioctl handling, but this makes it work for now at least. Signed-off-by: Jens Axboe diff --git a/drivers/block/mtip32xx/mtip32xx.c b/drivers/block/mtip32xx/mtip32xx.c index 847b8ff..1cf2b04 100644 --- a/drivers/block/mtip32xx/mtip32xx.c +++ b/drivers/block/mtip32xx/mtip32xx.c @@ -85,6 +85,7 @@ int mtip_major; static DEFINE_SPINLOCK(rssd_index_lock); static DEFINE_IDA(rssd_index_ida); +#ifdef CONFIG_COMPAT struct mtip_compat_ide_task_request_s { __u8 io_ports[8]; __u8 hob_ports[8]; @@ -95,6 +96,7 @@ struct mtip_compat_ide_task_request_s { compat_ulong_t out_size; compat_ulong_t in_size; }; +#endif static int mtip_exec_internal_command(struct mtip_port *port, void *fis, @@ -1628,9 +1630,9 @@ static int exec_drive_taskfile(struct driver_data *dd, ide_task_request_t *req_task; u8 *outbuf = NULL; u8 *inbuf = NULL; - dma_addr_t outbuf_dma = (dma_addr_t)NULL; - dma_addr_t inbuf_dma = (dma_addr_t)NULL; - dma_addr_t dma_buffer = (dma_addr_t)NULL; + dma_addr_t outbuf_dma = 0; + dma_addr_t inbuf_dma = 0; + dma_addr_t dma_buffer = 0; int err = 0; int tasksize = sizeof(struct ide_task_request_s); unsigned int taskin = 0; @@ -1642,14 +1644,18 @@ static int exec_drive_taskfile(struct driver_data *dd, unsigned int transfer_size; unsigned long task_file_data; int intotal, outtotal; +#ifdef CONFIG_COMPAT struct mtip_compat_ide_task_request_s *compat_req_task = NULL; int compat_tasksize = sizeof(struct mtip_compat_ide_task_request_s); +#endif + req_task = kzalloc(tasksize, GFP_KERNEL); if (req_task == NULL) return -ENOMEM; if (compat == 1) { +#ifdef CONFIG_COMPAT compat_req_task = (struct mtip_compat_ide_task_request_s __user *) arg; @@ -1672,6 +1678,10 @@ static int exec_drive_taskfile(struct driver_data *dd, outtotal = compat_tasksize; intotal = compat_tasksize + req_task->out_size; +#else + outtotal = 0; + intotal = 0; +#endif } else { if (copy_from_user(req_task, buf, tasksize)) { kfree(req_task); @@ -1705,7 +1715,7 @@ static int exec_drive_taskfile(struct driver_data *dd, outbuf, taskout, DMA_TO_DEVICE); - if (outbuf_dma == (dma_addr_t)NULL) { + if (outbuf_dma == 0) { err = -ENOMEM; goto abort; } @@ -1726,7 +1736,7 @@ static int exec_drive_taskfile(struct driver_data *dd, inbuf_dma = pci_map_single(dd->pdev, inbuf, taskin, DMA_FROM_DEVICE); - if (inbuf_dma == (dma_addr_t)NULL) { + if (inbuf_dma == 0) { err = -ENOMEM; goto abort; } @@ -1868,8 +1878,8 @@ static int exec_drive_taskfile(struct driver_data *dd, if (outbuf_dma) pci_unmap_single(dd->pdev, outbuf_dma, taskout, DMA_TO_DEVICE); - inbuf_dma = (dma_addr_t) NULL; - outbuf_dma = (dma_addr_t) NULL; + inbuf_dma = 0; + outbuf_dma = 0; /* return the ATA registers to the caller.*/ req_task->io_ports[1] = reply->features; @@ -1913,6 +1923,7 @@ static int exec_drive_taskfile(struct driver_data *dd, up_write(&dd->internal_sem); if (compat == 1) { +#ifdef CONFIG_COMPAT if (copy_to_user(buf, req_task, compat_tasksize - (2 * sizeof(compat_long_t)))) { @@ -1928,6 +1939,7 @@ static int exec_drive_taskfile(struct driver_data *dd, err = -EFAULT; goto abort; } +#endif } else { if (copy_to_user(buf, req_task, tasksize)) { err = -EFAULT; @@ -2873,6 +2885,7 @@ static int mtip_block_ioctl(struct block_device *dev, } } +#ifdef CONFIG_COMPAT /* * Block layer compat IOCTL handler. * @@ -2906,6 +2919,7 @@ static int mtip_block_compat_ioctl(struct block_device *dev, return mtip_hw_ioctl(dd, cmd, arg, 1); } } +#endif /* * Obtain the geometry of the device. @@ -2959,7 +2973,9 @@ static int mtip_block_getgeo(struct block_device *dev, */ static const struct block_device_operations mtip_block_ops = { .ioctl = mtip_block_ioctl, +#ifdef CONFIG_COMPAT .compat_ioctl = mtip_block_compat_ioctl, +#endif .getgeo = mtip_block_getgeo, .owner = THIS_MODULE }; -- cgit v0.10.2 From ef0f1587343a4c17b9b0d9061546e36c1c1bb2ec Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Tue, 27 Sep 2011 21:19:53 -0600 Subject: mtip32xx: cleanup compat ioctl handling Do the conversion/copy up front instead of passing in a compat flag to the ioctl handler and subsequently to the exec_drive_taskfile() function. Signed-off-by: Jens Axboe diff --git a/drivers/block/mtip32xx/mtip32xx.c b/drivers/block/mtip32xx/mtip32xx.c index 1cf2b04..d58581b 100644 --- a/drivers/block/mtip32xx/mtip32xx.c +++ b/drivers/block/mtip32xx/mtip32xx.c @@ -1622,76 +1622,26 @@ static unsigned int implicit_sector(unsigned char command, * See ide_taskfile_ioctl() for derivation */ static int exec_drive_taskfile(struct driver_data *dd, - unsigned long arg, - unsigned char compat) + void __user *buf, + ide_task_request_t *req_task, + int outtotal) { struct host_to_dev_fis fis; struct host_to_dev_fis *reply; - ide_task_request_t *req_task; u8 *outbuf = NULL; u8 *inbuf = NULL; dma_addr_t outbuf_dma = 0; dma_addr_t inbuf_dma = 0; dma_addr_t dma_buffer = 0; int err = 0; - int tasksize = sizeof(struct ide_task_request_s); unsigned int taskin = 0; unsigned int taskout = 0; u8 nsect = 0; - char __user *buf = (char __user *)arg; unsigned int timeout = MTIP_IOCTL_COMMAND_TIMEOUT_MS; unsigned int force_single_sector; unsigned int transfer_size; unsigned long task_file_data; - int intotal, outtotal; -#ifdef CONFIG_COMPAT - struct mtip_compat_ide_task_request_s *compat_req_task = NULL; - int compat_tasksize = sizeof(struct mtip_compat_ide_task_request_s); -#endif - - - req_task = kzalloc(tasksize, GFP_KERNEL); - if (req_task == NULL) - return -ENOMEM; - - if (compat == 1) { -#ifdef CONFIG_COMPAT - compat_req_task = - (struct mtip_compat_ide_task_request_s __user *) arg; - - if (copy_from_user(req_task, buf, - compat_tasksize - - (2 * sizeof(compat_long_t)))) { - err = -EFAULT; - goto abort; - } - - if (get_user(req_task->out_size, &compat_req_task->out_size)) { - err = -EFAULT; - goto abort; - } - - if (get_user(req_task->in_size, &compat_req_task->in_size)) { - err = -EFAULT; - goto abort; - } - - outtotal = compat_tasksize; - intotal = compat_tasksize + req_task->out_size; -#else - outtotal = 0; - intotal = 0; -#endif - } else { - if (copy_from_user(req_task, buf, tasksize)) { - kfree(req_task); - err = -EFAULT; - goto abort; - } - - outtotal = tasksize; - intotal = tasksize + req_task->out_size; - } + int intotal = outtotal + req_task->out_size; taskout = req_task->out_size; taskin = req_task->in_size; @@ -1922,30 +1872,6 @@ static int exec_drive_taskfile(struct driver_data *dd, up_write(&dd->internal_sem); - if (compat == 1) { -#ifdef CONFIG_COMPAT - if (copy_to_user(buf, req_task, - compat_tasksize - - (2 * sizeof(compat_long_t)))) { - err = -EFAULT; - goto abort; - } - if (put_user(req_task->out_size, - &compat_req_task->out_size)) { - err = -EFAULT; - goto abort; - } - if (put_user(req_task->in_size, &compat_req_task->in_size)) { - err = -EFAULT; - goto abort; - } -#endif - } else { - if (copy_to_user(buf, req_task, tasksize)) { - err = -EFAULT; - goto abort; - } - } if (taskout) { if (copy_to_user(buf + outtotal, outbuf, taskout)) { err = -EFAULT; @@ -1965,7 +1891,6 @@ abort: if (outbuf_dma) pci_unmap_single(dd->pdev, outbuf_dma, taskout, DMA_TO_DEVICE); - kfree(req_task); kfree(outbuf); kfree(inbuf); @@ -1989,10 +1914,8 @@ abort: * -EFAULT An error occurred copying data to a user space buffer. * -EIO An error occurred while executing the command. */ -int mtip_hw_ioctl(struct driver_data *dd, - unsigned int cmd, - unsigned long arg, - unsigned char compat) +static int mtip_hw_ioctl(struct driver_data *dd, unsigned int cmd, + unsigned long arg) { switch (cmd) { case HDIO_GET_IDENTITY: @@ -2049,8 +1972,24 @@ int mtip_hw_ioctl(struct driver_data *dd, break; } - case HDIO_DRIVE_TASKFILE: - return exec_drive_taskfile(dd, arg, compat); + case HDIO_DRIVE_TASKFILE: { + ide_task_request_t req_task; + int ret, outtotal; + + if (copy_from_user(&req_task, (void __user *) arg, + sizeof(req_task))) + return -EFAULT; + + outtotal = sizeof(req_task); + + ret = exec_drive_taskfile(dd, (void __user *) arg, + &req_task, outtotal); + + if (copy_to_user((void __user *) arg, &req_task, sizeof(req_task))) + return -EFAULT; + + return ret; + } default: return -EINVAL; @@ -2881,7 +2820,7 @@ static int mtip_block_ioctl(struct block_device *dev, case BLKFLSBUF: return 0; default: - return mtip_hw_ioctl(dd, cmd, arg, 0); + return mtip_hw_ioctl(dd, cmd, arg); } } @@ -2915,8 +2854,46 @@ static int mtip_block_compat_ioctl(struct block_device *dev, switch (cmd) { case BLKFLSBUF: return 0; + case HDIO_DRIVE_TASKFILE: { + struct mtip_compat_ide_task_request_s *compat_req_task; + ide_task_request_t req_task; + int compat_tasksize, outtotal, ret; + + compat_tasksize = sizeof(struct mtip_compat_ide_task_request_s); + + compat_req_task = + (struct mtip_compat_ide_task_request_s __user *) arg; + + if (copy_from_user(&req_task, (void __user *) arg, + compat_tasksize - (2 * sizeof(compat_long_t)))) + return -EFAULT; + + if (get_user(req_task.out_size, &compat_req_task->out_size)) + return -EFAULT; + + if (get_user(req_task.in_size, &compat_req_task->in_size)) + return -EFAULT; + + outtotal = sizeof(struct mtip_compat_ide_task_request_s); + + ret = exec_drive_taskfile(dd, (void __user *) arg, + &req_task, outtotal); + + if (copy_to_user((void __user *) arg, &req_task, + compat_tasksize - + (2 * sizeof(compat_long_t)))) + return -EFAULT; + + if (put_user(req_task.out_size, &compat_req_task->out_size)) + return -EFAULT; + + if (put_user(req_task.in_size, &compat_req_task->in_size)) + return -EFAULT; + + return ret; + } default: - return mtip_hw_ioctl(dd, cmd, arg, 1); + return mtip_hw_ioctl(dd, cmd, arg); } } #endif diff --git a/drivers/block/mtip32xx/mtip32xx.h b/drivers/block/mtip32xx/mtip32xx.h index 3423d18..d6355c6 100644 --- a/drivers/block/mtip32xx/mtip32xx.h +++ b/drivers/block/mtip32xx/mtip32xx.h @@ -430,10 +430,6 @@ extern void mtip_hw_submit_io(struct driver_data *dd, void *data, int barrier, int dir); -extern int mtip_hw_ioctl(struct driver_data *dd, - unsigned int cmd, - unsigned long arg, - unsigned char compat); extern int mtip_hw_sysfs_init(struct driver_data *dd, struct kobject *kobj); extern int mtip_hw_sysfs_exit(struct driver_data *dd, struct kobject *kobj); extern int mtip_hw_resume(struct driver_data *dd); -- cgit v0.10.2 From 6316668fbcf8a0a166830e7e84cdbdf0ab9392c8 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Tue, 27 Sep 2011 21:27:43 -0600 Subject: mtip32xx: ensure that all local functions are static Kill the declarations in the header file and mark them as static. Reshuffle a few functions to ensure that everything is properly declared before being used. Signed-off-by: Jens Axboe diff --git a/drivers/block/mtip32xx/mtip32xx.c b/drivers/block/mtip32xx/mtip32xx.c index d58581b..40d840e 100644 --- a/drivers/block/mtip32xx/mtip32xx.c +++ b/drivers/block/mtip32xx/mtip32xx.c @@ -108,6 +108,72 @@ static int mtip_exec_internal_command(struct mtip_port *port, unsigned long timeout); /* + * This function check_for_surprise_removal is called + * while card is removed from the system and it will + * read the vendor id from the configration space + * + * @pdev Pointer to the pci_dev structure. + * + * return value + * true if device removed, else false + */ +static bool mtip_check_surprise_removal(struct pci_dev *pdev) +{ + u16 vendor_id = 0; + + /* Read the vendorID from the configuration space */ + pci_read_config_word(pdev, 0x00, &vendor_id); + if (vendor_id == 0xFFFF) + return true; /* device removed */ + + return false; /* device present */ +} + +/* + * This function is called for clean the pending command in the + * command slot during the surprise removal of device and return + * error to the upper layer. + * + * @dd Pointer to the DRIVER_DATA structure. + * + * return value + * None + */ +static void mtip_command_cleanup(struct driver_data *dd) +{ + int group = 0, commandslot = 0, commandindex = 0; + struct mtip_cmd *command; + struct mtip_port *port = dd->port; + + for (group = 0; group < 4; group++) { + for (commandslot = 0; commandslot < 32; commandslot++) { + if (!(port->allocated[group] & (1 << commandslot))) + continue; + + commandindex = group << 5 | commandslot; + command = &port->commands[commandindex]; + + if (atomic_read(&command->active) + && (command->async_callback)) { + command->async_callback(command->async_data, + -ENODEV); + command->async_callback = NULL; + command->async_data = NULL; + } + + dma_unmap_sg(&port->dd->pdev->dev, + command->sg, + command->scatter_ents, + command->direction); + } + } + + up(&port->cmd_slot); + + atomic_set(&dd->drv_cleanup_done, true); +} + +/* * Obtain an empty command slot. * * This function needs to be reentrant since it could be called @@ -167,214 +233,72 @@ static inline void release_slot(struct mtip_port *port, int tag) } /* - * Issue a command to the hardware. - * - * Set the appropriate bit in the s_active and Command Issue hardware - * registers, causing hardware command processing to begin. - * - * @port Pointer to the port structure. - * @tag The tag of the command to be issued. + * Reset the HBA (without sleeping) * - * return value - * None - */ -static inline void mtip_issue_ncq_command(struct mtip_port *port, int tag) -{ - unsigned long flags = 0; - - atomic_set(&port->commands[tag].active, 1); - - spin_lock_irqsave(&port->cmd_issue_lock, flags); - - writel((1 << MTIP_TAG_BIT(tag)), - port->s_active[MTIP_TAG_INDEX(tag)]); - writel((1 << MTIP_TAG_BIT(tag)), - port->cmd_issue[MTIP_TAG_INDEX(tag)]); - - spin_unlock_irqrestore(&port->cmd_issue_lock, flags); -} - -/* - * Called periodically to see if any read/write commands are - * taking too long to complete. + * Just like hba_reset, except does not call sleep, so can be + * run from interrupt/tasklet context. * - * @data Pointer to the PORT data structure. + * @dd Pointer to the driver data structure. * * return value - * None + * 0 The reset was successful. + * -1 The HBA Reset bit did not clear. */ -void mtip_timeout_function(unsigned long int data) +static int hba_reset_nosleep(struct driver_data *dd) { - struct mtip_port *port = (struct mtip_port *) data; - struct host_to_dev_fis *fis; - struct mtip_cmd *command; - int tag, cmdto_cnt = 0; - unsigned int bit, group; - unsigned int num_command_slots = port->dd->slot_groups * 32; - - if (unlikely(!port)) - return; - - if (atomic_read(&port->dd->resumeflag) == true) { - mod_timer(&port->cmd_timer, - jiffies + msecs_to_jiffies(30000)); - return; - } - - for (tag = 0; tag < num_command_slots; tag++) { - /* - * Skip internal command slot as it has - * its own timeout mechanism - */ - if (tag == MTIP_TAG_INTERNAL) - continue; - - if (atomic_read(&port->commands[tag].active) && - (time_after(jiffies, port->commands[tag].comp_time))) { - group = tag >> 5; - bit = tag & 0x1f; - - command = &port->commands[tag]; - fis = (struct host_to_dev_fis *) command->command; - - dev_warn(&port->dd->pdev->dev, - "Timeout for command tag %d\n", tag); - - cmdto_cnt++; - if (cmdto_cnt == 1) - atomic_inc(&port->dd->eh_active); - - /* - * Clear the completed bit. This should prevent - * any interrupt handlers from trying to retire - * the command. - */ - writel(1 << bit, port->completed[group]); + unsigned long timeout; - /* Call the async completion callback. */ - if (likely(command->async_callback)) - command->async_callback(command->async_data, - -EIO); - command->async_callback = NULL; - command->comp_func = NULL; + /* Chip quirk: quiesce any chip function */ + mdelay(10); - /* Unmap the DMA scatter list entries */ - dma_unmap_sg(&port->dd->pdev->dev, - command->sg, - command->scatter_ents, - command->direction); + /* Set the reset bit */ + writel(HOST_RESET, dd->mmio + HOST_CTL); - /* - * Clear the allocated bit and active tag for the - * command. - */ - atomic_set(&port->commands[tag].active, 0); - release_slot(port, tag); + /* Flush */ + readl(dd->mmio + HOST_CTL); - up(&port->cmd_slot); - } - } + /* + * Wait 10ms then spin for up to 1 second + * waiting for reset acknowledgement + */ + timeout = jiffies + msecs_to_jiffies(1000); + mdelay(10); + while ((readl(dd->mmio + HOST_CTL) & HOST_RESET) + && time_before(jiffies, timeout)) + mdelay(1); - if (cmdto_cnt) { - dev_warn(&port->dd->pdev->dev, - "%d commands timed out: restarting port", - cmdto_cnt); - mtip_restart_port(port); - atomic_dec(&port->dd->eh_active); - } + if (readl(dd->mmio + HOST_CTL) & HOST_RESET) + return -1; - /* Restart the timer */ - mod_timer(&port->cmd_timer, - jiffies + msecs_to_jiffies(MTIP_TIMEOUT_CHECK_PERIOD)); + return 0; } /* - * IO completion function. + * Issue a command to the hardware. * - * This completion function is called by the driver ISR when a - * command that was issued by the kernel completes. It first calls the - * asynchronous completion function which normally calls back into the block - * layer passing the asynchronous callback data, then unmaps the - * scatter list associated with the completed command, and finally - * clears the allocated bit associated with the completed command. + * Set the appropriate bit in the s_active and Command Issue hardware + * registers, causing hardware command processing to begin. * - * @port Pointer to the port data structure. - * @tag Tag of the command. - * @data Pointer to driver_data. - * @status Completion status. + * @port Pointer to the port structure. + * @tag The tag of the command to be issued. * * return value - * None + * None */ -static void mtip_async_complete(struct mtip_port *port, - int tag, - void *data, - int status) +static inline void mtip_issue_ncq_command(struct mtip_port *port, int tag) { - struct mtip_cmd *command; - struct driver_data *dd = data; - int cb_status = status ? -EIO : 0; - - if (unlikely(!dd) || unlikely(!port)) - return; - - command = &port->commands[tag]; - - if (unlikely(status == PORT_IRQ_TF_ERR)) { - dev_warn(&port->dd->pdev->dev, - "Command tag %d failed due to TFE\n", tag); - } - - /* Upper layer callback */ - if (likely(command->async_callback)) - command->async_callback(command->async_data, cb_status); - - command->async_callback = NULL; - command->comp_func = NULL; - - /* Unmap the DMA scatter list entries */ - dma_unmap_sg(&dd->pdev->dev, - command->sg, - command->scatter_ents, - command->direction); - - /* Clear the allocated and active bits for the command */ - atomic_set(&port->commands[tag].active, 0); - release_slot(port, tag); + unsigned long flags = 0; - up(&port->cmd_slot); -} + atomic_set(&port->commands[tag].active, 1); -/* - * Internal command completion callback function. - * - * This function is normally called by the driver ISR when an internal - * command completed. This function signals the command completion by - * calling complete(). - * - * @port Pointer to the port data structure. - * @tag Tag of the command that has completed. - * @data Pointer to a completion structure. - * @status Completion status. - * - * return value - * None - */ -static void mtip_completion(struct mtip_port *port, - int tag, - void *data, - int status) -{ - struct mtip_cmd *command = &port->commands[tag]; - struct completion *waiting = data; - if (unlikely(status == PORT_IRQ_TF_ERR)) - dev_warn(&port->dd->pdev->dev, - "Internal command %d completed with TFE\n", tag); + spin_lock_irqsave(&port->cmd_issue_lock, flags); - command->async_callback = NULL; - command->comp_func = NULL; + writel((1 << MTIP_TAG_BIT(tag)), + port->s_active[MTIP_TAG_INDEX(tag)]); + writel((1 << MTIP_TAG_BIT(tag)), + port->cmd_issue[MTIP_TAG_INDEX(tag)]); - complete(waiting); + spin_unlock_irqrestore(&port->cmd_issue_lock, flags); } /* @@ -496,56 +420,15 @@ static void mtip_init_port(struct mtip_port *port) /* Clear SError */ writel(readl(port->mmio + PORT_SCR_ERR), port->mmio + PORT_SCR_ERR); - /* reset the completed registers.*/ - for (i = 0; i < port->dd->slot_groups; i++) - writel(0xFFFFFFFF, port->completed[i]); - - /* Clear any pending interrupts for this port */ - writel(readl(port->mmio + PORT_IRQ_STAT), port->mmio + PORT_IRQ_STAT); - - /* Enable port interrupts */ - writel(DEF_PORT_IRQ, port->mmio + PORT_IRQ_MASK); -} - -/* - * Reset the HBA (without sleeping) - * - * Just like hba_reset, except does not call sleep, so can be - * run from interrupt/tasklet context. - * - * @dd Pointer to the driver data structure. - * - * return value - * 0 The reset was successful. - * -1 The HBA Reset bit did not clear. - */ -int hba_reset_nosleep(struct driver_data *dd) -{ - unsigned long timeout; - - /* Chip quirk: quiesce any chip function */ - mdelay(10); - - /* Set the reset bit */ - writel(HOST_RESET, dd->mmio + HOST_CTL); - - /* Flush */ - readl(dd->mmio + HOST_CTL); - - /* - * Wait 10ms then spin for up to 1 second - * waiting for reset acknowledgement - */ - timeout = jiffies + msecs_to_jiffies(1000); - mdelay(10); - while ((readl(dd->mmio + HOST_CTL) & HOST_RESET) - && time_before(jiffies, timeout)) - mdelay(1); + /* reset the completed registers.*/ + for (i = 0; i < port->dd->slot_groups; i++) + writel(0xFFFFFFFF, port->completed[i]); - if (readl(dd->mmio + HOST_CTL) & HOST_RESET) - return -1; + /* Clear any pending interrupts for this port */ + writel(readl(port->mmio + PORT_IRQ_STAT), port->mmio + PORT_IRQ_STAT); - return 0; + /* Enable port interrupts */ + writel(DEF_PORT_IRQ, port->mmio + PORT_IRQ_MASK); } /* @@ -556,7 +439,7 @@ int hba_reset_nosleep(struct driver_data *dd) * return value * None */ -void mtip_restart_port(struct mtip_port *port) +static void mtip_restart_port(struct mtip_port *port) { unsigned long timeout; @@ -620,6 +503,189 @@ void mtip_restart_port(struct mtip_port *port) } /* + * Called periodically to see if any read/write commands are + * taking too long to complete. + * + * @data Pointer to the PORT data structure. + * + * return value + * None + */ +static void mtip_timeout_function(unsigned long int data) +{ + struct mtip_port *port = (struct mtip_port *) data; + struct host_to_dev_fis *fis; + struct mtip_cmd *command; + int tag, cmdto_cnt = 0; + unsigned int bit, group; + unsigned int num_command_slots = port->dd->slot_groups * 32; + + if (unlikely(!port)) + return; + + if (atomic_read(&port->dd->resumeflag) == true) { + mod_timer(&port->cmd_timer, + jiffies + msecs_to_jiffies(30000)); + return; + } + + for (tag = 0; tag < num_command_slots; tag++) { + /* + * Skip internal command slot as it has + * its own timeout mechanism + */ + if (tag == MTIP_TAG_INTERNAL) + continue; + + if (atomic_read(&port->commands[tag].active) && + (time_after(jiffies, port->commands[tag].comp_time))) { + group = tag >> 5; + bit = tag & 0x1f; + + command = &port->commands[tag]; + fis = (struct host_to_dev_fis *) command->command; + + dev_warn(&port->dd->pdev->dev, + "Timeout for command tag %d\n", tag); + + cmdto_cnt++; + if (cmdto_cnt == 1) + atomic_inc(&port->dd->eh_active); + + /* + * Clear the completed bit. This should prevent + * any interrupt handlers from trying to retire + * the command. + */ + writel(1 << bit, port->completed[group]); + + /* Call the async completion callback. */ + if (likely(command->async_callback)) + command->async_callback(command->async_data, + -EIO); + command->async_callback = NULL; + command->comp_func = NULL; + + /* Unmap the DMA scatter list entries */ + dma_unmap_sg(&port->dd->pdev->dev, + command->sg, + command->scatter_ents, + command->direction); + + /* + * Clear the allocated bit and active tag for the + * command. + */ + atomic_set(&port->commands[tag].active, 0); + release_slot(port, tag); + + up(&port->cmd_slot); + } + } + + if (cmdto_cnt) { + dev_warn(&port->dd->pdev->dev, + "%d commands timed out: restarting port", + cmdto_cnt); + mtip_restart_port(port); + atomic_dec(&port->dd->eh_active); + } + + /* Restart the timer */ + mod_timer(&port->cmd_timer, + jiffies + msecs_to_jiffies(MTIP_TIMEOUT_CHECK_PERIOD)); +} + +/* + * IO completion function. + * + * This completion function is called by the driver ISR when a + * command that was issued by the kernel completes. It first calls the + * asynchronous completion function which normally calls back into the block + * layer passing the asynchronous callback data, then unmaps the + * scatter list associated with the completed command, and finally + * clears the allocated bit associated with the completed command. + * + * @port Pointer to the port data structure. + * @tag Tag of the command. + * @data Pointer to driver_data. + * @status Completion status. + * + * return value + * None + */ +static void mtip_async_complete(struct mtip_port *port, + int tag, + void *data, + int status) +{ + struct mtip_cmd *command; + struct driver_data *dd = data; + int cb_status = status ? -EIO : 0; + + if (unlikely(!dd) || unlikely(!port)) + return; + + command = &port->commands[tag]; + + if (unlikely(status == PORT_IRQ_TF_ERR)) { + dev_warn(&port->dd->pdev->dev, + "Command tag %d failed due to TFE\n", tag); + } + + /* Upper layer callback */ + if (likely(command->async_callback)) + command->async_callback(command->async_data, cb_status); + + command->async_callback = NULL; + command->comp_func = NULL; + + /* Unmap the DMA scatter list entries */ + dma_unmap_sg(&dd->pdev->dev, + command->sg, + command->scatter_ents, + command->direction); + + /* Clear the allocated and active bits for the command */ + atomic_set(&port->commands[tag].active, 0); + release_slot(port, tag); + + up(&port->cmd_slot); +} + +/* + * Internal command completion callback function. + * + * This function is normally called by the driver ISR when an internal + * command completed. This function signals the command completion by + * calling complete(). + * + * @port Pointer to the port data structure. + * @tag Tag of the command that has completed. + * @data Pointer to a completion structure. + * @status Completion status. + * + * return value + * None + */ +static void mtip_completion(struct mtip_port *port, + int tag, + void *data, + int status) +{ + struct mtip_cmd *command = &port->commands[tag]; + struct completion *waiting = data; + if (unlikely(status == PORT_IRQ_TF_ERR)) + dev_warn(&port->dd->pdev->dev, + "Internal command %d completed with TFE\n", tag); + + command->async_callback = NULL; + command->comp_func = NULL; + + complete(waiting); +} + +/* * Helper function for tag logging */ static void print_tags(struct driver_data *dd, @@ -1276,7 +1342,7 @@ static int mtip_standby_immediate(struct mtip_port *port) * 1 Capacity was returned successfully. * 0 The identify information is invalid. */ -bool mtip_hw_get_capacity(struct driver_data *dd, sector_t *sectors) +static bool mtip_hw_get_capacity(struct driver_data *dd, sector_t *sectors) { struct mtip_port *port = dd->port; u64 total, raw0, raw1, raw2, raw3; @@ -1423,7 +1489,7 @@ static inline void fill_command_sg(struct driver_data *dd, * return value 0 The command completed successfully. * return value -1 An error occurred while executing the command. */ -int exec_drive_task(struct mtip_port *port, u8 *command) +static int exec_drive_task(struct mtip_port *port, u8 *command) { struct host_to_dev_fis fis; struct host_to_dev_fis *reply = (port->rxfis + RX_FIS_D2H_REG); @@ -1499,8 +1565,8 @@ int exec_drive_task(struct mtip_port *port, u8 *command) * data to the user space buffer. * return value -1 An error occurred while executing the command. */ -int exec_drive_command(struct mtip_port *port, u8 *command, - void __user *user_buffer) +static int exec_drive_command(struct mtip_port *port, u8 *command, + void __user *user_buffer) { struct host_to_dev_fis fis; struct host_to_dev_fis *reply = (port->rxfis + RX_FIS_D2H_REG); @@ -2020,15 +2086,9 @@ static int mtip_hw_ioctl(struct driver_data *dd, unsigned int cmd, * return value * None */ -void mtip_hw_submit_io(struct driver_data *dd, - sector_t start, - int nsect, - int nents, - int tag, - void *callback, - void *data, - int barrier, - int dir) +static void mtip_hw_submit_io(struct driver_data *dd, sector_t start, + int nsect, int nents, int tag, void *callback, + void *data, int barrier, int dir) { struct host_to_dev_fis *fis; struct mtip_port *port = dd->port; @@ -2115,7 +2175,7 @@ void mtip_hw_submit_io(struct driver_data *dd, * return value * None */ -void mtip_hw_release_scatterlist(struct driver_data *dd, int tag) +static void mtip_hw_release_scatterlist(struct driver_data *dd, int tag) { release_slot(dd->port, tag); } @@ -2131,8 +2191,8 @@ void mtip_hw_release_scatterlist(struct driver_data *dd, int tag) * Pointer to the scatter list for the allocated command slot * or NULL if no command slots are available. */ -struct scatterlist *mtip_hw_get_scatterlist(struct driver_data *dd, - int *tag) +static struct scatterlist *mtip_hw_get_scatterlist(struct driver_data *dd, + int *tag) { /* * It is possible that, even with this semaphore, a thread @@ -2216,7 +2276,7 @@ static DEVICE_ATTR(registers, S_IRUGO, hw_show_registers, NULL); * 0 Operation completed successfully. * -EINVAL Invalid parameter. */ -int mtip_hw_sysfs_init(struct driver_data *dd, struct kobject *kobj) +static int mtip_hw_sysfs_init(struct driver_data *dd, struct kobject *kobj) { if (!kobj || !dd) return -EINVAL; @@ -2237,7 +2297,7 @@ int mtip_hw_sysfs_init(struct driver_data *dd, struct kobject *kobj) * 0 Operation completed successfully. * -EINVAL Invalid parameter. */ -int mtip_hw_sysfs_exit(struct driver_data *dd, struct kobject *kobj) +static int mtip_hw_sysfs_exit(struct driver_data *dd, struct kobject *kobj) { if (!kobj || !dd) return -EINVAL; @@ -2385,7 +2445,7 @@ static int mtip_ftl_rebuild_poll(struct driver_data *dd) * return value * 0 on success, else an error code. */ -int mtip_hw_init(struct driver_data *dd) +static int mtip_hw_init(struct driver_data *dd) { int i; int rv; @@ -2586,7 +2646,7 @@ out1: * return value * 0 */ -int mtip_hw_exit(struct driver_data *dd) +static int mtip_hw_exit(struct driver_data *dd) { /* * Send standby immediate (E0h) to the drive so that it @@ -2634,7 +2694,7 @@ int mtip_hw_exit(struct driver_data *dd) * return value * 0 */ -int mtip_hw_shutdown(struct driver_data *dd) +static int mtip_hw_shutdown(struct driver_data *dd) { /* * Send standby immediate (E0h) to the drive so that it @@ -2657,7 +2717,7 @@ int mtip_hw_shutdown(struct driver_data *dd) * 0 Suspend was successful * -EFAULT Suspend was not successful */ -int mtip_hw_suspend(struct driver_data *dd) +static int mtip_hw_suspend(struct driver_data *dd) { /* * Send standby immediate (E0h) to the drive @@ -2689,7 +2749,7 @@ int mtip_hw_suspend(struct driver_data *dd) * 0 Resume was successful * -EFAULT Resume was not successful */ -int mtip_hw_resume(struct driver_data *dd) +static int mtip_hw_resume(struct driver_data *dd) { /* Perform any needed hardware setup steps */ hba_setup(dd); @@ -2716,50 +2776,6 @@ int mtip_hw_resume(struct driver_data *dd) } /* - * This function is called for clean the pending command in the - * command slot during the surprise removal of device and return - * error to the upper layer. - * - * @dd Pointer to the DRIVER_DATA structure. - * - * return value - * None - */ -void mtip_command_cleanup(struct driver_data *dd) -{ - int group = 0, commandslot = 0, commandindex = 0; - struct mtip_cmd *command; - struct mtip_port *port = dd->port; - - for (group = 0; group < 4; group++) { - for (commandslot = 0; commandslot < 32; commandslot++) { - if (!(port->allocated[group] & (1 << commandslot))) - continue; - - commandindex = group << 5 | commandslot; - command = &port->commands[commandindex]; - - if (atomic_read(&command->active) - && (command->async_callback)) { - command->async_callback(command->async_data, - -ENODEV); - command->async_callback = NULL; - command->async_data = NULL; - } - - dma_unmap_sg(&port->dd->pdev->dev, - command->sg, - command->scatter_ents, - command->direction); - } - } - - up(&port->cmd_slot); - - atomic_set(&dd->drv_cleanup_done, true); -} - -/* * Helper function for reusing disk name * upon hot insertion. */ @@ -3037,7 +3053,7 @@ static int mtip_make_request(struct request_queue *queue, struct bio *bio) * return value * 0 on success else an error code. */ -int mtip_block_initialize(struct driver_data *dd) +static int mtip_block_initialize(struct driver_data *dd) { int rv = 0; sector_t capacity; @@ -3168,7 +3184,7 @@ protocol_init_error: * return value * 0 */ -int mtip_block_remove(struct driver_data *dd) +static int mtip_block_remove(struct driver_data *dd) { struct kobject *kobj; /* Clean up the sysfs attributes managed by the protocol layer. */ @@ -3205,7 +3221,7 @@ int mtip_block_remove(struct driver_data *dd) * return value * 0 */ -int mtip_block_shutdown(struct driver_data *dd) +static int mtip_block_shutdown(struct driver_data *dd) { dev_info(&dd->pdev->dev, "Shutting down %s ...\n", dd->disk->disk_name); @@ -3220,7 +3236,7 @@ int mtip_block_shutdown(struct driver_data *dd) return 0; } -int mtip_block_suspend(struct driver_data *dd) +static int mtip_block_suspend(struct driver_data *dd) { dev_info(&dd->pdev->dev, "Suspending %s ...\n", dd->disk->disk_name); @@ -3228,7 +3244,7 @@ int mtip_block_suspend(struct driver_data *dd) return 0; } -int mtip_block_resume(struct driver_data *dd) +static int mtip_block_resume(struct driver_data *dd) { dev_info(&dd->pdev->dev, "Resuming %s ...\n", dd->disk->disk_name); @@ -3479,28 +3495,6 @@ static void mtip_pci_shutdown(struct pci_dev *pdev) mtip_block_shutdown(dd); } -/* - * This function check_for_surprise_removal is called - * while card is removed from the system and it will - * read the vendor id from the configration space - * - * @pdev Pointer to the pci_dev structure. - * - * return value - * true if device removed, else false - */ -bool mtip_check_surprise_removal(struct pci_dev *pdev) -{ - u16 vendor_id = 0; - - /* Read the vendorID from the configuration space */ - pci_read_config_word(pdev, 0x00, &vendor_id); - if (vendor_id == 0xFFFF) - return true; /* device removed */ - - return false; /* device present */ -} - /* Table of device ids supported by this driver. */ static DEFINE_PCI_DEVICE_TABLE(mtip_pci_tbl) = { { PCI_DEVICE(PCI_VENDOR_ID_MICRON, P320_DEVICE_ID) }, diff --git a/drivers/block/mtip32xx/mtip32xx.h b/drivers/block/mtip32xx/mtip32xx.h index d6355c6..17be4f4 100644 --- a/drivers/block/mtip32xx/mtip32xx.h +++ b/drivers/block/mtip32xx/mtip32xx.h @@ -405,37 +405,4 @@ struct driver_data { atomic_t eh_active; /* Flag for error handling tracking */ }; -/* Function declarations */ -extern int mtip_block_initialize(struct driver_data *dd); -extern int mtip_block_remove(struct driver_data *dd); -extern int mtip_block_shutdown(struct driver_data *dd); -extern int mtip_block_suspend(struct driver_data *dd); -extern int mtip_block_resume(struct driver_data *dd); -extern int mtip_hw_init(struct driver_data *dd); -extern int mtip_hw_exit(struct driver_data *dd); -extern int mtip_hw_shutdown(struct driver_data *dd); -extern bool mtip_hw_get_capacity(struct driver_data *dd, sector_t *sectors); -extern void mtip_hw_release_scatterlist( - struct driver_data *dd, - int tag); -extern struct scatterlist *mtip_hw_get_scatterlist( - struct driver_data *dd, - int *tag); -extern void mtip_hw_submit_io(struct driver_data *dd, - sector_t start, - int nsect, - int nents, - int tag, - void *callback, - void *data, - int barrier, - int dir); -extern int mtip_hw_sysfs_init(struct driver_data *dd, struct kobject *kobj); -extern int mtip_hw_sysfs_exit(struct driver_data *dd, struct kobject *kobj); -extern int mtip_hw_resume(struct driver_data *dd); -extern int mtip_hw_suspend(struct driver_data *dd); -void mtip_command_cleanup(struct driver_data *dd); -bool mtip_check_surprise_removal(struct pci_dev *pdev); -void mtip_restart_port(struct mtip_port *port); - #endif -- cgit v0.10.2 From 3ff147d3a88e43135b1861d964496101657fa9a2 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Tue, 27 Sep 2011 21:33:53 -0600 Subject: mtip32xx: mark a few more items static Missed two items: mtip_major, and mtip_pci_driver. Signed-off-by: Jens Axboe diff --git a/drivers/block/mtip32xx/mtip32xx.c b/drivers/block/mtip32xx/mtip32xx.c index 40d840e..b426a93 100644 --- a/drivers/block/mtip32xx/mtip32xx.c +++ b/drivers/block/mtip32xx/mtip32xx.c @@ -80,7 +80,7 @@ static int instance; * Global variable used to hold the major block device number * allocated in mtip_init(). */ -int mtip_major; +static int mtip_major; static DEFINE_SPINLOCK(rssd_index_lock); static DEFINE_IDA(rssd_index_ida); @@ -3502,7 +3502,7 @@ static DEFINE_PCI_DEVICE_TABLE(mtip_pci_tbl) = { }; /* Structure that describes the PCI driver functions. */ -struct pci_driver mtip_pci_driver = { +static struct pci_driver mtip_pci_driver = { .name = MTIP_DRV_NAME, .id_table = mtip_pci_tbl, .probe = mtip_pci_probe, -- cgit v0.10.2 From 0e838c624e04490985162a1b00d7aa1956c8834e Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Wed, 28 Sep 2011 07:35:40 -0600 Subject: mtip32xx: add module.h include to avoid conflict with moduleh tree Signed-off-by: Jens Axboe diff --git a/drivers/block/mtip32xx/mtip32xx.c b/drivers/block/mtip32xx/mtip32xx.c index b426a93..f7a3321 100644 --- a/drivers/block/mtip32xx/mtip32xx.c +++ b/drivers/block/mtip32xx/mtip32xx.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include -- cgit v0.10.2 From a71f483d7957c74368a76a3a88ae54d524fa3b49 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Sat, 5 Nov 2011 08:36:21 +0100 Subject: mtip32xx: update to new ->make_request() API Signed-off-by: Jens Axboe diff --git a/drivers/block/mtip32xx/mtip32xx.c b/drivers/block/mtip32xx/mtip32xx.c index f7a3321..880facb 100644 --- a/drivers/block/mtip32xx/mtip32xx.c +++ b/drivers/block/mtip32xx/mtip32xx.c @@ -2984,10 +2984,8 @@ static const struct block_device_operations mtip_block_ops = { * the driver data structure. * @bio Pointer to the BIO. * - * return value - * 0 */ -static int mtip_make_request(struct request_queue *queue, struct bio *bio) +static void mtip_make_request(struct request_queue *queue, struct bio *bio) { struct driver_data *dd = queue->queuedata; struct scatterlist *sg; @@ -2998,12 +2996,12 @@ static int mtip_make_request(struct request_queue *queue, struct bio *bio) if (unlikely(!bio_has_data(bio))) { blk_queue_flush(queue, 0); bio_endio(bio, 0); - return 0; + return; } if (unlikely(atomic_read(&dd->eh_active))) { bio_endio(bio, -EBUSY); - return 0; + return; } sg = mtip_hw_get_scatterlist(dd, &tag); @@ -3015,7 +3013,7 @@ static int mtip_make_request(struct request_queue *queue, struct bio *bio) "Maximum number of SGL entries exceeded"); bio_io_error(bio); mtip_hw_release_scatterlist(dd, tag); - return 0; + return; } /* Create the scatter list for this bio. */ @@ -3036,11 +3034,8 @@ static int mtip_make_request(struct request_queue *queue, struct bio *bio) bio, bio->bi_rw & REQ_FLUSH, bio_data_dir(bio)); - } else { + } else bio_io_error(bio); - } - - return 0; } /* -- cgit v0.10.2 From b3c7d453a00b7dadc2a7435f68b012371ccc3a3e Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Thu, 3 Nov 2011 06:57:08 -0300 Subject: [media] solo6x10: rename jpeg.h to solo6x10-jpeg.h This header clashes with the jpeg.h in gspca when doing a compatibility build using the media_build system. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/staging/media/solo6x10/jpeg.h b/drivers/staging/media/solo6x10/jpeg.h deleted file mode 100644 index 50defec..0000000 --- a/drivers/staging/media/solo6x10/jpeg.h +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright (C) 2010 Bluecherry, LLC www.bluecherrydvr.com - * Copyright (C) 2010 Ben Collins - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifndef __SOLO6X10_JPEG_H -#define __SOLO6X10_JPEG_H - -static unsigned char jpeg_header[] = { - 0xff, 0xd8, 0xff, 0xfe, 0x00, 0x0d, 0x42, 0x6c, - 0x75, 0x65, 0x63, 0x68, 0x65, 0x72, 0x72, 0x79, - 0x20, 0xff, 0xdb, 0x00, 0x43, 0x00, 0x20, 0x16, - 0x18, 0x1c, 0x18, 0x14, 0x20, 0x1c, 0x1a, 0x1c, - 0x24, 0x22, 0x20, 0x26, 0x30, 0x50, 0x34, 0x30, - 0x2c, 0x2c, 0x30, 0x62, 0x46, 0x4a, 0x3a, 0x50, - 0x74, 0x66, 0x7a, 0x78, 0x72, 0x66, 0x70, 0x6e, - 0x80, 0x90, 0xb8, 0x9c, 0x80, 0x88, 0xae, 0x8a, - 0x6e, 0x70, 0xa0, 0xda, 0xa2, 0xae, 0xbe, 0xc4, - 0xce, 0xd0, 0xce, 0x7c, 0x9a, 0xe2, 0xf2, 0xe0, - 0xc8, 0xf0, 0xb8, 0xca, 0xce, 0xc6, 0xff, 0xdb, - 0x00, 0x43, 0x01, 0x22, 0x24, 0x24, 0x30, 0x2a, - 0x30, 0x5e, 0x34, 0x34, 0x5e, 0xc6, 0x84, 0x70, - 0x84, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, - 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, - 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, - 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, - 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, - 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, - 0xc6, 0xc6, 0xc6, 0xff, 0xc4, 0x01, 0xa2, 0x00, - 0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x10, 0x00, 0x02, 0x01, - 0x03, 0x03, 0x02, 0x04, 0x03, 0x05, 0x05, 0x04, - 0x04, 0x00, 0x00, 0x01, 0x7d, 0x01, 0x02, 0x03, - 0x00, 0x04, 0x11, 0x05, 0x12, 0x21, 0x31, 0x41, - 0x06, 0x13, 0x51, 0x61, 0x07, 0x22, 0x71, 0x14, - 0x32, 0x81, 0x91, 0xa1, 0x08, 0x23, 0x42, 0xb1, - 0xc1, 0x15, 0x52, 0xd1, 0xf0, 0x24, 0x33, 0x62, - 0x72, 0x82, 0x09, 0x0a, 0x16, 0x17, 0x18, 0x19, - 0x1a, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x34, - 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, - 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x53, 0x54, - 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x63, 0x64, - 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x73, 0x74, - 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x83, 0x84, - 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x92, 0x93, - 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, - 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, - 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, - 0xba, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, - 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, - 0xd8, 0xd9, 0xda, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, - 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf1, 0xf2, 0xf3, - 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0x01, - 0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x11, 0x00, 0x02, 0x01, - 0x02, 0x04, 0x04, 0x03, 0x04, 0x07, 0x05, 0x04, - 0x04, 0x00, 0x01, 0x02, 0x77, 0x00, 0x01, 0x02, - 0x03, 0x11, 0x04, 0x05, 0x21, 0x31, 0x06, 0x12, - 0x41, 0x51, 0x07, 0x61, 0x71, 0x13, 0x22, 0x32, - 0x81, 0x08, 0x14, 0x42, 0x91, 0xa1, 0xb1, 0xc1, - 0x09, 0x23, 0x33, 0x52, 0xf0, 0x15, 0x62, 0x72, - 0xd1, 0x0a, 0x16, 0x24, 0x34, 0xe1, 0x25, 0xf1, - 0x17, 0x18, 0x19, 0x1a, 0x26, 0x27, 0x28, 0x29, - 0x2a, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, - 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x53, - 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x63, - 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x73, - 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x82, - 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, - 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, - 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, - 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, - 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, - 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, - 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe2, 0xe3, 0xe4, - 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf2, 0xf3, - 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xff, - 0xc0, 0x00, 0x11, 0x08, 0x00, 0xf0, 0x02, 0xc0, - 0x03, 0x01, 0x22, 0x00, 0x02, 0x11, 0x01, 0x03, - 0x11, 0x01, 0xff, 0xda, 0x00, 0x0c, 0x03, 0x01, - 0x00, 0x02, 0x11, 0x03, 0x11, 0x00, 0x3f, 0x00 -}; - -/* This is the byte marker for the start of SOF0: 0xffc0 marker */ -#define SOF0_START 575 - -#endif /* __SOLO6X10_JPEG_H */ diff --git a/drivers/staging/media/solo6x10/solo6x10-jpeg.h b/drivers/staging/media/solo6x10/solo6x10-jpeg.h new file mode 100644 index 0000000..50defec --- /dev/null +++ b/drivers/staging/media/solo6x10/solo6x10-jpeg.h @@ -0,0 +1,105 @@ +/* + * Copyright (C) 2010 Bluecherry, LLC www.bluecherrydvr.com + * Copyright (C) 2010 Ben Collins + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef __SOLO6X10_JPEG_H +#define __SOLO6X10_JPEG_H + +static unsigned char jpeg_header[] = { + 0xff, 0xd8, 0xff, 0xfe, 0x00, 0x0d, 0x42, 0x6c, + 0x75, 0x65, 0x63, 0x68, 0x65, 0x72, 0x72, 0x79, + 0x20, 0xff, 0xdb, 0x00, 0x43, 0x00, 0x20, 0x16, + 0x18, 0x1c, 0x18, 0x14, 0x20, 0x1c, 0x1a, 0x1c, + 0x24, 0x22, 0x20, 0x26, 0x30, 0x50, 0x34, 0x30, + 0x2c, 0x2c, 0x30, 0x62, 0x46, 0x4a, 0x3a, 0x50, + 0x74, 0x66, 0x7a, 0x78, 0x72, 0x66, 0x70, 0x6e, + 0x80, 0x90, 0xb8, 0x9c, 0x80, 0x88, 0xae, 0x8a, + 0x6e, 0x70, 0xa0, 0xda, 0xa2, 0xae, 0xbe, 0xc4, + 0xce, 0xd0, 0xce, 0x7c, 0x9a, 0xe2, 0xf2, 0xe0, + 0xc8, 0xf0, 0xb8, 0xca, 0xce, 0xc6, 0xff, 0xdb, + 0x00, 0x43, 0x01, 0x22, 0x24, 0x24, 0x30, 0x2a, + 0x30, 0x5e, 0x34, 0x34, 0x5e, 0xc6, 0x84, 0x70, + 0x84, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, + 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, + 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, + 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, + 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, + 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, + 0xc6, 0xc6, 0xc6, 0xff, 0xc4, 0x01, 0xa2, 0x00, + 0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x10, 0x00, 0x02, 0x01, + 0x03, 0x03, 0x02, 0x04, 0x03, 0x05, 0x05, 0x04, + 0x04, 0x00, 0x00, 0x01, 0x7d, 0x01, 0x02, 0x03, + 0x00, 0x04, 0x11, 0x05, 0x12, 0x21, 0x31, 0x41, + 0x06, 0x13, 0x51, 0x61, 0x07, 0x22, 0x71, 0x14, + 0x32, 0x81, 0x91, 0xa1, 0x08, 0x23, 0x42, 0xb1, + 0xc1, 0x15, 0x52, 0xd1, 0xf0, 0x24, 0x33, 0x62, + 0x72, 0x82, 0x09, 0x0a, 0x16, 0x17, 0x18, 0x19, + 0x1a, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x34, + 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, + 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x53, 0x54, + 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x63, 0x64, + 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x73, 0x74, + 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x83, 0x84, + 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x92, 0x93, + 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, + 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, + 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, + 0xba, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, + 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, + 0xd8, 0xd9, 0xda, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, + 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf1, 0xf2, 0xf3, + 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0x01, + 0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x11, 0x00, 0x02, 0x01, + 0x02, 0x04, 0x04, 0x03, 0x04, 0x07, 0x05, 0x04, + 0x04, 0x00, 0x01, 0x02, 0x77, 0x00, 0x01, 0x02, + 0x03, 0x11, 0x04, 0x05, 0x21, 0x31, 0x06, 0x12, + 0x41, 0x51, 0x07, 0x61, 0x71, 0x13, 0x22, 0x32, + 0x81, 0x08, 0x14, 0x42, 0x91, 0xa1, 0xb1, 0xc1, + 0x09, 0x23, 0x33, 0x52, 0xf0, 0x15, 0x62, 0x72, + 0xd1, 0x0a, 0x16, 0x24, 0x34, 0xe1, 0x25, 0xf1, + 0x17, 0x18, 0x19, 0x1a, 0x26, 0x27, 0x28, 0x29, + 0x2a, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, + 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x53, + 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x63, + 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x73, + 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x82, + 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, + 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, + 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, + 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, + 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, + 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, + 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe2, 0xe3, 0xe4, + 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf2, 0xf3, + 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xff, + 0xc0, 0x00, 0x11, 0x08, 0x00, 0xf0, 0x02, 0xc0, + 0x03, 0x01, 0x22, 0x00, 0x02, 0x11, 0x01, 0x03, + 0x11, 0x01, 0xff, 0xda, 0x00, 0x0c, 0x03, 0x01, + 0x00, 0x02, 0x11, 0x03, 0x11, 0x00, 0x3f, 0x00 +}; + +/* This is the byte marker for the start of SOF0: 0xffc0 marker */ +#define SOF0_START 575 + +#endif /* __SOLO6X10_JPEG_H */ diff --git a/drivers/staging/media/solo6x10/v4l2-enc.c b/drivers/staging/media/solo6x10/v4l2-enc.c index bee7280..f8f0da9 100644 --- a/drivers/staging/media/solo6x10/v4l2-enc.c +++ b/drivers/staging/media/solo6x10/v4l2-enc.c @@ -26,7 +26,7 @@ #include #include "solo6x10.h" #include "tw28.h" -#include "jpeg.h" +#include "solo6x10-jpeg.h" #define MIN_VID_BUFFERS 4 #define FRAME_BUF_SIZE (128 * 1024) -- cgit v0.10.2 From 33cdf5b0e75142096d79cbe3cb7c3dc797499562 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 4 Nov 2011 06:13:14 -0300 Subject: [media] solo6x10: fix broken Makefile The Makefile used := instead of +=, this broke the compatibility build. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/staging/media/solo6x10/Makefile b/drivers/staging/media/solo6x10/Makefile index 72816cf..337e38c 100644 --- a/drivers/staging/media/solo6x10/Makefile +++ b/drivers/staging/media/solo6x10/Makefile @@ -1,3 +1,3 @@ solo6x10-y := core.o i2c.o p2m.o v4l2.o tw28.o gpio.o disp.o enc.o v4l2-enc.o g723.o -obj-$(CONFIG_SOLO6X10) := solo6x10.o +obj-$(CONFIG_SOLO6X10) += solo6x10.o -- cgit v0.10.2 From b682ad1d178d1686a4db07535d1e611342cde012 Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Fri, 12 Aug 2011 18:29:10 -0300 Subject: [media] tda18212: add DVB-T2 support Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/common/tuners/tda18212.c b/drivers/media/common/tuners/tda18212.c index e29cc2b..6374a1e 100644 --- a/drivers/media/common/tuners/tda18212.c +++ b/drivers/media/common/tuners/tda18212.c @@ -136,12 +136,24 @@ static int tda18212_set_params(struct dvb_frontend *fe, int ret, i; u32 if_khz; u8 buf[9]; + #define DVBT_6 0 + #define DVBT_7 1 + #define DVBT_8 2 + #define DVBT2_6 3 + #define DVBT2_7 4 + #define DVBT2_8 5 + #define DVBC_6 6 + #define DVBC_8 7 static const u8 bw_params[][3] = { - /* 0f 13 23 */ - { 0xb3, 0x20, 0x03 }, /* DVB-T 6 MHz */ - { 0xb3, 0x31, 0x01 }, /* DVB-T 7 MHz */ - { 0xb3, 0x22, 0x01 }, /* DVB-T 8 MHz */ - { 0x92, 0x53, 0x03 }, /* DVB-C */ + /* reg: 0f 13 23 */ + [DVBT_6] = { 0xb3, 0x20, 0x03 }, + [DVBT_7] = { 0xb3, 0x31, 0x01 }, + [DVBT_8] = { 0xb3, 0x22, 0x01 }, + [DVBT2_6] = { 0xbc, 0x20, 0x03 }, + [DVBT2_7] = { 0xbc, 0x72, 0x03 }, + [DVBT2_8] = { 0xbc, 0x22, 0x01 }, + [DVBC_6] = { 0x92, 0x50, 0x03 }, + [DVBC_8] = { 0x92, 0x53, 0x03 }, }; dbg("delsys=%d RF=%d BW=%d\n", @@ -155,15 +167,34 @@ static int tda18212_set_params(struct dvb_frontend *fe, switch (c->bandwidth_hz) { case 6000000: if_khz = priv->cfg->if_dvbt_6; - i = 0; + i = DVBT_6; break; case 7000000: if_khz = priv->cfg->if_dvbt_7; - i = 1; + i = DVBT_7; break; case 8000000: if_khz = priv->cfg->if_dvbt_8; - i = 2; + i = DVBT_8; + break; + default: + ret = -EINVAL; + goto error; + } + break; + case SYS_DVBT2: + switch (c->bandwidth_hz) { + case 6000000: + if_khz = priv->cfg->if_dvbt2_6; + i = DVBT2_6; + break; + case 7000000: + if_khz = priv->cfg->if_dvbt2_7; + i = DVBT2_7; + break; + case 8000000: + if_khz = priv->cfg->if_dvbt2_8; + i = DVBT2_8; break; default: ret = -EINVAL; @@ -172,7 +203,7 @@ static int tda18212_set_params(struct dvb_frontend *fe, break; case SYS_DVBC_ANNEX_AC: if_khz = priv->cfg->if_dvbc; - i = 3; + i = DVBC_8; break; default: ret = -EINVAL; diff --git a/drivers/media/common/tuners/tda18212.h b/drivers/media/common/tuners/tda18212.h index 83b497f..9bd5da4 100644 --- a/drivers/media/common/tuners/tda18212.h +++ b/drivers/media/common/tuners/tda18212.h @@ -29,6 +29,10 @@ struct tda18212_config { u16 if_dvbt_6; u16 if_dvbt_7; u16 if_dvbt_8; + u16 if_dvbt2_5; + u16 if_dvbt2_6; + u16 if_dvbt2_7; + u16 if_dvbt2_8; u16 if_dvbc; }; -- cgit v0.10.2 From 608add85decc7a13194072fbb0c6aadc89d394e5 Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Fri, 12 Aug 2011 18:29:46 -0300 Subject: [media] anysee: add support for Anysee E7 T2C Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/dvb/dvb-usb/Kconfig b/drivers/media/dvb/dvb-usb/Kconfig index 5825716..3e316f2 100644 --- a/drivers/media/dvb/dvb-usb/Kconfig +++ b/drivers/media/dvb/dvb-usb/Kconfig @@ -311,6 +311,7 @@ config DVB_USB_ANYSEE select DVB_STV0900 if !DVB_FE_CUSTOMISE select DVB_STV6110 if !DVB_FE_CUSTOMISE select DVB_ISL6423 if !DVB_FE_CUSTOMISE + select DVB_CXD2820R if !DVB_FE_CUSTOMISE help Say Y here to support the Anysee E30, Anysee E30 Plus or Anysee E30 C Plus DVB USB2.0 receiver. diff --git a/drivers/media/dvb/dvb-usb/anysee.c b/drivers/media/dvb/dvb-usb/anysee.c index 5f2278b..9c1ed3b 100644 --- a/drivers/media/dvb/dvb-usb/anysee.c +++ b/drivers/media/dvb/dvb-usb/anysee.c @@ -41,6 +41,7 @@ #include "stv0900.h" #include "stv6110.h" #include "isl6423.h" +#include "cxd2820r.h" /* debug */ static int dvb_usb_anysee_debug; @@ -309,6 +310,17 @@ static struct tda18212_config anysee_tda18212_config = { .if_dvbc = 5000, }; +static struct tda18212_config anysee_tda18212_config2 = { + .i2c_address = 0x60 /* (0xc0 >> 1) */, + .if_dvbt_6 = 3550, + .if_dvbt_7 = 3700, + .if_dvbt_8 = 4150, + .if_dvbt2_6 = 3250, + .if_dvbt2_7 = 4000, + .if_dvbt2_8 = 4000, + .if_dvbc = 5000, +}; + static struct cx24116_config anysee_cx24116_config = { .demod_address = (0xaa >> 1), .mpg_clk_pos_pol = 0x00, @@ -339,6 +351,18 @@ static struct isl6423_config anysee_isl6423_config = { .addr = (0x10 >> 1), }; +static struct cxd2820r_config anysee_cxd2820r_config = { + .i2c_address = 0x6d, /* (0xda >> 1) */ + .ts_mode = 0x38, + .if_dvbt_6 = 3550, + .if_dvbt_7 = 3700, + .if_dvbt_8 = 4150, + .if_dvbt2_6 = 3250, + .if_dvbt2_7 = 4000, + .if_dvbt2_8 = 4000, + .if_dvbc = 5000, +}; + /* * New USB device strings: Mfr=1, Product=2, SerialNumber=0 * Manufacturer: AMT.CO.KR @@ -421,6 +445,14 @@ static struct isl6423_config anysee_isl6423_config = { * IOA[7] TS 1=enabled * IOE[5] STV0903 1=enabled * + * E7 T2C VID=1c73 PID=861f HW=20 FW=0.1 AMTCI=0.5 "anysee-E7T2C(LP)" + * PCB: 508T2C (rev0.3) + * parts: DNOQ44QCH106A(CXD2820R, TDA18212), TDA8024 + * OEA=80 OEB=00 OEC=03 OED=f7 OEE=ff + * IOA=4d IOB=00 IOC=cc IOD=48 IOE=e4 + * IOA[7] TS 1=enabled + * IOE[5] CXD2820R 1=enabled + * * E7 PTC VID=1c73 PID=861f HW=21 FW=0.1 AMTCI=?? "anysee-E7PTC(LP)" * PCB: 508PTC (rev0.5) * parts: ZL10353, TDA10023, DNOD44CDH086A(TDA18212) @@ -437,7 +469,7 @@ static struct isl6423_config anysee_isl6423_config = { * IOD[6] ZL10353 1=enabled * IOE[0] IF 0=enabled * - * E7 S2 VID=1c73 PID=861f HW=22 FW=0.1 AMTCI=?? "anysee-E7PS2(LP)" + * E7 PS2 VID=1c73 PID=861f HW=22 FW=0.1 AMTCI=?? "anysee-E7PS2(LP)" * PCB: 508PS2 (rev0.4) * parts: DNBU10512IST(STV0903, STV6110), ISL6423 * OEA=80 OEB=00 OEC=03 OED=f7 OEE=ff @@ -818,6 +850,32 @@ static int anysee_frontend_attach(struct dvb_usb_adapter *adap) &adap->dev->i2c_adap, 0); break; + case ANYSEE_HW_508T2C: /* 20 */ + /* E7 T2C */ + + /* enable transport stream on IOA[7] */ + ret = anysee_wr_reg_mask(adap->dev, REG_IOA, (1 << 7), 0x80); + if (ret) + goto error; + + /* enable DVB-T/T2/C demod on IOE[5] */ + ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (1 << 5), 0x20); + if (ret) + goto error; + + if (state->fe_id == 0) { + /* DVB-T/T2 */ + adap->fe[0] = dvb_attach(cxd2820r_attach, + &anysee_cxd2820r_config, + &adap->dev->i2c_adap, NULL); + } else { + /* DVB-C */ + adap->fe[1] = dvb_attach(cxd2820r_attach, + &anysee_cxd2820r_config, + &adap->dev->i2c_adap, adap->fe[0]); + } + + break; } if (!adap->fe_adap[0].fe) { @@ -930,6 +988,15 @@ static int anysee_tuner_attach(struct dvb_usb_adapter *adap) } break; + + case ANYSEE_HW_508T2C: /* 20 */ + /* E7 T2C */ + + /* attach tuner */ + fe = dvb_attach(tda18212_attach, adap->fe[state->fe_id], + &adap->dev->i2c_adap, &anysee_tda18212_config2); + + break; default: fe = NULL; } diff --git a/drivers/media/dvb/dvb-usb/anysee.h b/drivers/media/dvb/dvb-usb/anysee.h index 57ee500..da32350 100644 --- a/drivers/media/dvb/dvb-usb/anysee.h +++ b/drivers/media/dvb/dvb-usb/anysee.h @@ -69,6 +69,7 @@ struct anysee_state { #define ANYSEE_HW_507FA 15 /* E30 Combo Plus / E30 C Plus */ #define ANYSEE_HW_508TC 18 /* E7 TC */ #define ANYSEE_HW_508S2 19 /* E7 S2 */ +#define ANYSEE_HW_508T2C 20 /* E7 T2C */ #define ANYSEE_HW_508PTC 21 /* E7 PTC Plus */ #define ANYSEE_HW_508PS2 22 /* E7 PS2 Plus */ -- cgit v0.10.2 From be94351e592cb71fb61aa8eeed7bf3f877dc6fff Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Mon, 5 Sep 2011 22:10:05 -0300 Subject: [media] anysee: I2C gate control DNOD44CDH086A tuner module DNOD44CDH086A (NXP TDA18212) tuner module is not connected to demodulator I2C gate. Instead demodulator gate it uses external GPIO driven gate. Override demodulator I2C gate control with own in that case. Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/dvb/dvb-usb/anysee.c b/drivers/media/dvb/dvb-usb/anysee.c index 9c1ed3b..28c7b23 100644 --- a/drivers/media/dvb/dvb-usb/anysee.c +++ b/drivers/media/dvb/dvb-usb/anysee.c @@ -478,6 +478,16 @@ static struct cxd2820r_config anysee_cxd2820r_config = { * IOE[5] STV0903 1=enabled */ + +/* external I2C gate used for DNOD44CDH086A(TDA18212) tuner module */ +static int anysee_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) +{ + struct dvb_usb_adapter *adap = fe->dvb->priv; + + /* enable / disable tuner access on IOE[4] */ + return anysee_wr_reg_mask(adap->dev, REG_IOE, (enable << 4), 0x10); +} + static int anysee_frontend_ctrl(struct dvb_frontend *fe, int onoff) { struct dvb_usb_adapter *adap = fe->dvb->priv; @@ -779,6 +789,13 @@ static int anysee_frontend_attach(struct dvb_usb_adapter *adap) } } + /* I2C gate for DNOD44CDH086A(TDA18212) tuner module */ + if (tmp == 0xc7) { + if (adap->fe_adap[state->fe_id].fe) + adap->fe_adap[state->fe_id].fe->ops.i2c_gate_ctrl = + anysee_i2c_gate_ctrl; + } + break; case ANYSEE_HW_508TC: /* 18 */ case ANYSEE_HW_508PTC: /* 21 */ @@ -826,6 +843,11 @@ static int anysee_frontend_attach(struct dvb_usb_adapter *adap) &adap->dev->i2c_adap); } + /* I2C gate for DNOD44CDH086A(TDA18212) tuner module */ + if (adap->fe_adap[state->fe_id].fe) + adap->fe_adap[state->fe_id].fe->ops.i2c_gate_ctrl = + anysee_i2c_gate_ctrl; + break; case ANYSEE_HW_508S2: /* 19 */ case ANYSEE_HW_508PS2: /* 22 */ @@ -865,14 +887,14 @@ static int anysee_frontend_attach(struct dvb_usb_adapter *adap) if (state->fe_id == 0) { /* DVB-T/T2 */ - adap->fe[0] = dvb_attach(cxd2820r_attach, + adap->fe_adap[state->fe_id].fe = dvb_attach(cxd2820r_attach, &anysee_cxd2820r_config, &adap->dev->i2c_adap, NULL); } else { /* DVB-C */ - adap->fe[1] = dvb_attach(cxd2820r_attach, + adap->fe_adap[state->fe_id].fe = dvb_attach(cxd2820r_attach, &anysee_cxd2820r_config, - &adap->dev->i2c_adap, adap->fe[0]); + &adap->dev->i2c_adap, adap->fe_adap[0].fe); } break; @@ -935,22 +957,12 @@ static int anysee_tuner_attach(struct dvb_usb_adapter *adap) /* Try first attach TDA18212 silicon tuner on IOE[4], if that * fails attach old simple PLL. */ - /* enable tuner on IOE[4] */ - ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (1 << 4), 0x10); - if (ret) - goto error; - /* attach tuner */ fe = dvb_attach(tda18212_attach, adap->fe_adap[state->fe_id].fe, &adap->dev->i2c_adap, &anysee_tda18212_config); if (fe) break; - /* disable tuner on IOE[4] */ - ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (0 << 4), 0x10); - if (ret) - goto error; - /* attach tuner */ fe = dvb_attach(dvb_pll_attach, adap->fe_adap[state->fe_id].fe, (0xc0 >> 1), &adap->dev->i2c_adap, @@ -962,11 +974,6 @@ static int anysee_tuner_attach(struct dvb_usb_adapter *adap) /* E7 TC */ /* E7 PTC */ - /* enable tuner on IOE[4] */ - ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (1 << 4), 0x10); - if (ret) - goto error; - /* attach tuner */ fe = dvb_attach(tda18212_attach, adap->fe_adap[state->fe_id].fe, &adap->dev->i2c_adap, &anysee_tda18212_config); @@ -993,7 +1000,7 @@ static int anysee_tuner_attach(struct dvb_usb_adapter *adap) /* E7 T2C */ /* attach tuner */ - fe = dvb_attach(tda18212_attach, adap->fe[state->fe_id], + fe = dvb_attach(tda18212_attach, adap->fe_adap[state->fe_id].fe, &adap->dev->i2c_adap, &anysee_tda18212_config2); break; @@ -1006,7 +1013,6 @@ static int anysee_tuner_attach(struct dvb_usb_adapter *adap) else ret = -ENODEV; -error: return ret; } -- cgit v0.10.2 From 05cd37def5e697e158470d826cb75c5607c04bd1 Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Mon, 5 Sep 2011 23:33:04 -0300 Subject: [media] anysee: CI/CAM support Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/dvb/dvb-usb/anysee.c b/drivers/media/dvb/dvb-usb/anysee.c index 28c7b23..0bc1372 100644 --- a/drivers/media/dvb/dvb-usb/anysee.c +++ b/drivers/media/dvb/dvb-usb/anysee.c @@ -130,6 +130,29 @@ static int anysee_wr_reg_mask(struct dvb_usb_device *d, u16 reg, u8 val, return anysee_write_reg(d, reg, val); } +/* read single register with mask */ +static int anysee_rd_reg_mask(struct dvb_usb_device *d, u16 reg, u8 *val, + u8 mask) +{ + int ret, i; + u8 tmp; + + ret = anysee_read_reg(d, reg, &tmp); + if (ret) + return ret; + + tmp &= mask; + + /* find position of the first bit */ + for (i = 0; i < 8; i++) { + if ((mask >> i) & 0x01) + break; + } + *val = tmp >> i; + + return 0; +} + static int anysee_get_hw_info(struct dvb_usb_device *d, u8 *id) { u8 buf[] = {CMD_GET_HW_INFO}; @@ -157,22 +180,6 @@ static int anysee_ir_ctrl(struct dvb_usb_device *d, u8 onoff) return anysee_ctrl_msg(d, buf, sizeof(buf), NULL, 0); } -static int anysee_init(struct dvb_usb_device *d) -{ - int ret; - /* LED light */ - ret = anysee_led_ctrl(d, 0x01, 0x03); - if (ret) - return ret; - - /* enable IR */ - ret = anysee_ir_ctrl(d, 1); - if (ret) - return ret; - - return 0; -} - /* I2C */ static int anysee_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msg, int num) @@ -298,7 +305,7 @@ static struct tda10023_config anysee_tda10023_tda18212_config = { .pll_m = 12, .pll_p = 3, .pll_n = 1, - .output_mode = TDA10023_OUTPUT_MODE_PARALLEL_C, + .output_mode = TDA10023_OUTPUT_MODE_PARALLEL_B, .deltaf = 0xba02, }; @@ -802,11 +809,6 @@ static int anysee_frontend_attach(struct dvb_usb_adapter *adap) /* E7 TC */ /* E7 PTC */ - /* enable transport stream on IOA[7] */ - ret = anysee_wr_reg_mask(adap->dev, REG_IOA, (1 << 7), 0x80); - if (ret) - goto error; - if ((state->fe_id ^ dvb_usb_anysee_delsys) == 0) { /* disable DVB-T demod on IOD[6] */ ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (0 << 6), @@ -848,6 +850,8 @@ static int anysee_frontend_attach(struct dvb_usb_adapter *adap) adap->fe_adap[state->fe_id].fe->ops.i2c_gate_ctrl = anysee_i2c_gate_ctrl; + state->has_ci = true; + break; case ANYSEE_HW_508S2: /* 19 */ case ANYSEE_HW_508PS2: /* 22 */ @@ -857,11 +861,6 @@ static int anysee_frontend_attach(struct dvb_usb_adapter *adap) if (state->fe_id) break; - /* enable transport stream on IOA[7] */ - ret = anysee_wr_reg_mask(adap->dev, REG_IOA, (1 << 7), 0x80); - if (ret) - goto error; - /* enable DVB-S/S2 demod on IOE[5] */ ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (1 << 5), 0x20); if (ret) @@ -871,15 +870,12 @@ static int anysee_frontend_attach(struct dvb_usb_adapter *adap) adap->fe_adap[0].fe = dvb_attach(stv0900_attach, &anysee_stv0900_config, &adap->dev->i2c_adap, 0); + state->has_ci = true; + break; case ANYSEE_HW_508T2C: /* 20 */ /* E7 T2C */ - /* enable transport stream on IOA[7] */ - ret = anysee_wr_reg_mask(adap->dev, REG_IOA, (1 << 7), 0x80); - if (ret) - goto error; - /* enable DVB-T/T2/C demod on IOE[5] */ ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (1 << 5), 0x20); if (ret) @@ -897,6 +893,8 @@ static int anysee_frontend_attach(struct dvb_usb_adapter *adap) &adap->dev->i2c_adap, adap->fe_adap[0].fe); } + state->has_ci = true; + break; } @@ -1042,6 +1040,201 @@ static int anysee_rc_query(struct dvb_usb_device *d) return 0; } +static int anysee_ci_read_attribute_mem(struct dvb_ca_en50221 *ci, int slot, + int addr) +{ + struct dvb_usb_device *d = ci->data; + int ret; + u8 buf[] = {CMD_CI, 0x02, 0x40 | addr >> 8, addr & 0xff, 0x00, 1}; + u8 val; + + ret = anysee_ctrl_msg(d, buf, sizeof(buf), &val, 1); + if (ret) + return ret; + + return val; +} + +static int anysee_ci_write_attribute_mem(struct dvb_ca_en50221 *ci, int slot, + int addr, u8 val) +{ + struct dvb_usb_device *d = ci->data; + int ret; + u8 buf[] = {CMD_CI, 0x03, 0x40 | addr >> 8, addr & 0xff, 0x00, 1, val}; + + ret = anysee_ctrl_msg(d, buf, sizeof(buf), NULL, 0); + if (ret) + return ret; + + return 0; +} + +static int anysee_ci_read_cam_control(struct dvb_ca_en50221 *ci, int slot, + u8 addr) +{ + struct dvb_usb_device *d = ci->data; + int ret; + u8 buf[] = {CMD_CI, 0x04, 0x40, addr, 0x00, 1}; + u8 val; + + ret = anysee_ctrl_msg(d, buf, sizeof(buf), &val, 1); + if (ret) + return ret; + + return val; +} + +static int anysee_ci_write_cam_control(struct dvb_ca_en50221 *ci, int slot, + u8 addr, u8 val) +{ + struct dvb_usb_device *d = ci->data; + int ret; + u8 buf[] = {CMD_CI, 0x05, 0x40, addr, 0x00, 1, val}; + + ret = anysee_ctrl_msg(d, buf, sizeof(buf), NULL, 0); + if (ret) + return ret; + + return 0; +} + +static int anysee_ci_slot_reset(struct dvb_ca_en50221 *ci, int slot) +{ + struct dvb_usb_device *d = ci->data; + int ret; + struct anysee_state *state = d->priv; + + state->ci_cam_ready = jiffies + msecs_to_jiffies(1000); + + ret = anysee_wr_reg_mask(d, REG_IOA, (0 << 7), 0x80); + if (ret) + return ret; + + msleep(300); + + ret = anysee_wr_reg_mask(d, REG_IOA, (1 << 7), 0x80); + if (ret) + return ret; + + return 0; +} + +static int anysee_ci_slot_shutdown(struct dvb_ca_en50221 *ci, int slot) +{ + struct dvb_usb_device *d = ci->data; + int ret; + + ret = anysee_wr_reg_mask(d, REG_IOA, (0 << 7), 0x80); + if (ret) + return ret; + + msleep(30); + + ret = anysee_wr_reg_mask(d, REG_IOA, (1 << 7), 0x80); + if (ret) + return ret; + + return 0; +} + +static int anysee_ci_slot_ts_enable(struct dvb_ca_en50221 *ci, int slot) +{ + struct dvb_usb_device *d = ci->data; + int ret; + + ret = anysee_wr_reg_mask(d, REG_IOD, (0 << 1), 0x02); + if (ret) + return ret; + + return 0; +} + +static int anysee_ci_poll_slot_status(struct dvb_ca_en50221 *ci, int slot, + int open) +{ + struct dvb_usb_device *d = ci->data; + struct anysee_state *state = d->priv; + int ret; + u8 tmp; + + ret = anysee_rd_reg_mask(d, REG_IOC, &tmp, 0x40); + if (ret) + return ret; + + if (tmp == 0) { + ret = DVB_CA_EN50221_POLL_CAM_PRESENT; + if (time_after(jiffies, state->ci_cam_ready)) + ret |= DVB_CA_EN50221_POLL_CAM_READY; + } + + return ret; +} + +static int anysee_ci_init(struct dvb_usb_device *d) +{ + struct anysee_state *state = d->priv; + int ret; + + state->ci.owner = THIS_MODULE; + state->ci.read_attribute_mem = anysee_ci_read_attribute_mem; + state->ci.write_attribute_mem = anysee_ci_write_attribute_mem; + state->ci.read_cam_control = anysee_ci_read_cam_control; + state->ci.write_cam_control = anysee_ci_write_cam_control; + state->ci.slot_reset = anysee_ci_slot_reset; + state->ci.slot_shutdown = anysee_ci_slot_shutdown; + state->ci.slot_ts_enable = anysee_ci_slot_ts_enable; + state->ci.poll_slot_status = anysee_ci_poll_slot_status; + state->ci.data = d; + + ret = anysee_wr_reg_mask(d, REG_IOA, (1 << 7), 0x80); + if (ret) + return ret; + + ret = dvb_ca_en50221_init(&d->adapter[0].dvb_adap, &state->ci, 0, 1); + if (ret) + return ret; + + return 0; +} + +static void anysee_ci_release(struct dvb_usb_device *d) +{ + struct anysee_state *state = d->priv; + + /* detach CI */ + if (state->has_ci) + dvb_ca_en50221_release(&state->ci); + + return; +} + +static int anysee_init(struct dvb_usb_device *d) +{ + struct anysee_state *state = d->priv; + int ret; + + /* LED light */ + ret = anysee_led_ctrl(d, 0x01, 0x03); + if (ret) + return ret; + + /* enable IR */ + ret = anysee_ir_ctrl(d, 1); + if (ret) + return ret; + + /* attach CI */ + if (state->has_ci) { + ret = anysee_ci_init(d); + if (ret) { + state->has_ci = false; + return ret; + } + } + + return 0; +} + /* DVB USB Driver stuff */ static struct dvb_usb_device_properties anysee_properties; @@ -1083,6 +1276,16 @@ static int anysee_probe(struct usb_interface *intf, return anysee_init(d); } +static void anysee_disconnect(struct usb_interface *intf) +{ + struct dvb_usb_device *d = usb_get_intfdata(intf); + + anysee_ci_release(d); + dvb_usb_device_exit(intf); + + return; +} + static struct usb_device_id anysee_table[] = { { USB_DEVICE(USB_VID_CYPRESS, USB_PID_ANYSEE) }, { USB_DEVICE(USB_VID_AMT, USB_PID_ANYSEE) }, @@ -1160,7 +1363,7 @@ static struct dvb_usb_device_properties anysee_properties = { static struct usb_driver anysee_driver = { .name = "dvb_usb_anysee", .probe = anysee_probe, - .disconnect = dvb_usb_device_exit, + .disconnect = anysee_disconnect, .id_table = anysee_table, }; diff --git a/drivers/media/dvb/dvb-usb/anysee.h b/drivers/media/dvb/dvb-usb/anysee.h index da32350..8ac8794 100644 --- a/drivers/media/dvb/dvb-usb/anysee.h +++ b/drivers/media/dvb/dvb-usb/anysee.h @@ -36,6 +36,7 @@ #define DVB_USB_LOG_PREFIX "anysee" #include "dvb-usb.h" +#include "dvb_ca_en50221.h" #define deb_info(args...) dprintk(dvb_usb_anysee_debug, 0x01, args) #define deb_xfer(args...) dprintk(dvb_usb_anysee_debug, 0x02, args) @@ -54,12 +55,16 @@ enum cmd { CMD_GET_IR_CODE = 0x41, CMD_GET_HW_INFO = 0x19, CMD_SMARTCARD = 0x34, + CMD_CI = 0x37, }; struct anysee_state { u8 hw; /* PCB ID */ u8 seq; u8 fe_id:1; /* frondend ID */ + u8 has_ci:1; + struct dvb_ca_en50221 ci; + unsigned long ci_cam_ready; /* jiffies */ }; #define ANYSEE_HW_507T 2 /* E30 */ -- cgit v0.10.2 From 4048da2fa3c8c5088901d2adc4f7b5b5ccc05e79 Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Thu, 29 Sep 2011 20:28:53 -0300 Subject: [media] anysee: add control message debugs Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/dvb/dvb-usb/anysee.c b/drivers/media/dvb/dvb-usb/anysee.c index 0bc1372..2e70879 100644 --- a/drivers/media/dvb/dvb-usb/anysee.c +++ b/drivers/media/dvb/dvb-usb/anysee.c @@ -67,10 +67,12 @@ static int anysee_ctrl_msg(struct dvb_usb_device *d, u8 *sbuf, u8 slen, if (mutex_lock_interruptible(&anysee_usb_mutex) < 0) return -EAGAIN; + deb_xfer(">>> "); + debug_dump(buf, slen, deb_xfer); + /* We need receive one message more after dvb_usb_generic_rw due to weird transaction flow, which is 1 x send + 2 x receive. */ ret = dvb_usb_generic_rw(d, buf, sizeof(buf), buf, sizeof(buf), 0); - if (!ret) { /* receive 2nd answer */ ret = usb_bulk_msg(d->udev, usb_rcvbulkpipe(d->udev, @@ -80,7 +82,10 @@ static int anysee_ctrl_msg(struct dvb_usb_device *d, u8 *sbuf, u8 slen, err("%s: recv bulk message failed: %d", __func__, ret); else { deb_xfer("<<< "); - debug_dump(buf, act_len, deb_xfer); + debug_dump(buf, rlen, deb_xfer); + + if (buf[63] != 0x4f) + deb_info("%s: cmd failed\n", __func__); } } -- cgit v0.10.2 From 8f4ffb1d4752ebce153e88266ac1164e8ecc5854 Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Thu, 29 Sep 2011 20:36:33 -0300 Subject: [media] anysee: fix style issues Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/dvb/dvb-usb/anysee.c b/drivers/media/dvb/dvb-usb/anysee.c index 2e70879..c64eb56 100644 --- a/drivers/media/dvb/dvb-usb/anysee.c +++ b/drivers/media/dvb/dvb-usb/anysee.c @@ -631,7 +631,8 @@ static int anysee_frontend_attach(struct dvb_usb_adapter *adap) /* detect hardware only once */ if (adap->fe_adap[0].fe == NULL) { /* Check which hardware we have. - * We must do this call two times to get reliable values (hw bug). + * We must do this call two times to get reliable values + * (hw/fw bug). */ ret = anysee_get_hw_info(adap->dev, hw_info); if (ret) @@ -660,14 +661,14 @@ static int anysee_frontend_attach(struct dvb_usb_adapter *adap) break; /* attach demod */ - adap->fe_adap[0].fe = dvb_attach(mt352_attach, &anysee_mt352_config, - &adap->dev->i2c_adap); + adap->fe_adap[0].fe = dvb_attach(mt352_attach, + &anysee_mt352_config, &adap->dev->i2c_adap); if (adap->fe_adap[0].fe) break; /* attach demod */ - adap->fe_adap[0].fe = dvb_attach(zl10353_attach, &anysee_zl10353_config, - &adap->dev->i2c_adap); + adap->fe_adap[0].fe = dvb_attach(zl10353_attach, + &anysee_zl10353_config, &adap->dev->i2c_adap); break; case ANYSEE_HW_507CD: /* 6 */ @@ -719,8 +720,8 @@ static int anysee_frontend_attach(struct dvb_usb_adapter *adap) goto error; /* attach demod */ - adap->fe_adap[0].fe = dvb_attach(cx24116_attach, &anysee_cx24116_config, - &adap->dev->i2c_adap); + adap->fe_adap[0].fe = dvb_attach(cx24116_attach, + &anysee_cx24116_config, &adap->dev->i2c_adap); break; case ANYSEE_HW_507FA: /* 15 */ @@ -828,7 +829,8 @@ static int anysee_frontend_attach(struct dvb_usb_adapter *adap) goto error; /* attach demod */ - adap->fe_adap[state->fe_id].fe = dvb_attach(tda10023_attach, + adap->fe_adap[state->fe_id].fe = + dvb_attach(tda10023_attach, &anysee_tda10023_tda18212_config, &adap->dev->i2c_adap, 0x48); } else { @@ -845,7 +847,8 @@ static int anysee_frontend_attach(struct dvb_usb_adapter *adap) goto error; /* attach demod */ - adap->fe_adap[state->fe_id].fe = dvb_attach(zl10353_attach, + adap->fe_adap[state->fe_id].fe = + dvb_attach(zl10353_attach, &anysee_zl10353_tda18212_config, &adap->dev->i2c_adap); } @@ -872,8 +875,8 @@ static int anysee_frontend_attach(struct dvb_usb_adapter *adap) goto error; /* attach demod */ - adap->fe_adap[0].fe = dvb_attach(stv0900_attach, &anysee_stv0900_config, - &adap->dev->i2c_adap, 0); + adap->fe_adap[0].fe = dvb_attach(stv0900_attach, + &anysee_stv0900_config, &adap->dev->i2c_adap, 0); state->has_ci = true; @@ -888,12 +891,14 @@ static int anysee_frontend_attach(struct dvb_usb_adapter *adap) if (state->fe_id == 0) { /* DVB-T/T2 */ - adap->fe_adap[state->fe_id].fe = dvb_attach(cxd2820r_attach, + adap->fe_adap[state->fe_id].fe = + dvb_attach(cxd2820r_attach, &anysee_cxd2820r_config, &adap->dev->i2c_adap, NULL); } else { /* DVB-C */ - adap->fe_adap[state->fe_id].fe = dvb_attach(cxd2820r_attach, + adap->fe_adap[state->fe_id].fe = + dvb_attach(cxd2820r_attach, &anysee_cxd2820r_config, &adap->dev->i2c_adap, adap->fe_adap[0].fe); } @@ -925,24 +930,26 @@ static int anysee_tuner_attach(struct dvb_usb_adapter *adap) /* E30 */ /* attach tuner */ - fe = dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, (0xc2 >> 1), - NULL, DVB_PLL_THOMSON_DTT7579); + fe = dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, + (0xc2 >> 1), NULL, DVB_PLL_THOMSON_DTT7579); break; case ANYSEE_HW_507CD: /* 6 */ /* E30 Plus */ /* attach tuner */ - fe = dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, (0xc2 >> 1), - &adap->dev->i2c_adap, DVB_PLL_THOMSON_DTT7579); + fe = dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, + (0xc2 >> 1), &adap->dev->i2c_adap, + DVB_PLL_THOMSON_DTT7579); break; case ANYSEE_HW_507DC: /* 10 */ /* E30 C Plus */ /* attach tuner */ - fe = dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, (0xc0 >> 1), - &adap->dev->i2c_adap, DVB_PLL_SAMSUNG_DTOS403IH102A); + fe = dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, + (0xc0 >> 1), &adap->dev->i2c_adap, + DVB_PLL_SAMSUNG_DTOS403IH102A); break; case ANYSEE_HW_507SI: /* 11 */ @@ -1310,7 +1317,7 @@ static struct dvb_usb_device_properties anysee_properties = { { .num_frontends = 2, .frontend_ctrl = anysee_frontend_ctrl, - .fe = {{ + .fe = { { .streaming_ctrl = anysee_streaming_ctrl, .frontend_attach = anysee_frontend_attach, .tuner_attach = anysee_tuner_attach, @@ -1338,7 +1345,7 @@ static struct dvb_usb_device_properties anysee_properties = { } } }, - }}, + } }, } }, -- cgit v0.10.2 From 3f8770454b82c166662201a8966476f4538cbfeb Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Fri, 21 Oct 2011 09:30:25 -0300 Subject: [media] v4l: use i2c_smbus_read_word_swapped Function ensures that error codes don't get mangled. Dependant on: which is working it's way through the i2c tree. Signed-off-by: Jonathan Cameron Acked-by: Jean Delvare Acked-by: Robert Jarzmik Acked-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/mt9m001.c b/drivers/media/video/mt9m001.c index 63ae5c6..9f3ffc7 100644 --- a/drivers/media/video/mt9m001.c +++ b/drivers/media/video/mt9m001.c @@ -108,14 +108,13 @@ static struct mt9m001 *to_mt9m001(const struct i2c_client *client) static int reg_read(struct i2c_client *client, const u8 reg) { - s32 data = i2c_smbus_read_word_data(client, reg); - return data < 0 ? data : swab16(data); + return i2c_smbus_read_word_swapped(client, reg); } static int reg_write(struct i2c_client *client, const u8 reg, const u16 data) { - return i2c_smbus_write_word_data(client, reg, swab16(data)); + return i2c_smbus_write_word_swapped(client, reg, data); } static int reg_set(struct i2c_client *client, const u8 reg, diff --git a/drivers/media/video/mt9m111.c b/drivers/media/video/mt9m111.c index f023cc0..59bfe39 100644 --- a/drivers/media/video/mt9m111.c +++ b/drivers/media/video/mt9m111.c @@ -210,7 +210,7 @@ static int reg_page_map_set(struct i2c_client *client, const u16 reg) if (page > 2) return -EINVAL; - ret = i2c_smbus_write_word_data(client, MT9M111_PAGE_MAP, swab16(page)); + ret = i2c_smbus_write_word_swapped(client, MT9M111_PAGE_MAP, page); if (!ret) mt9m111->lastpage = page; return ret; @@ -222,7 +222,7 @@ static int mt9m111_reg_read(struct i2c_client *client, const u16 reg) ret = reg_page_map_set(client, reg); if (!ret) - ret = swab16(i2c_smbus_read_word_data(client, reg & 0xff)); + ret = i2c_smbus_read_word_swapped(client, reg & 0xff); dev_dbg(&client->dev, "read reg.%03x -> %04x\n", reg, ret); return ret; @@ -235,8 +235,7 @@ static int mt9m111_reg_write(struct i2c_client *client, const u16 reg, ret = reg_page_map_set(client, reg); if (!ret) - ret = i2c_smbus_write_word_data(client, reg & 0xff, - swab16(data)); + ret = i2c_smbus_write_word_swapped(client, reg & 0xff, data); dev_dbg(&client->dev, "write reg.%03x = %04x -> %d\n", reg, data, ret); return ret; } diff --git a/drivers/media/video/mt9t031.c b/drivers/media/video/mt9t031.c index 7ee84cc..198298c 100644 --- a/drivers/media/video/mt9t031.c +++ b/drivers/media/video/mt9t031.c @@ -89,14 +89,13 @@ static struct mt9t031 *to_mt9t031(const struct i2c_client *client) static int reg_read(struct i2c_client *client, const u8 reg) { - s32 data = i2c_smbus_read_word_data(client, reg); - return data < 0 ? data : swab16(data); + return i2c_smbus_read_word_swapped(client, reg); } static int reg_write(struct i2c_client *client, const u8 reg, const u16 data) { - return i2c_smbus_write_word_data(client, reg, swab16(data)); + return i2c_smbus_write_word_swapped(client, reg, data); } static int reg_set(struct i2c_client *client, const u8 reg, diff --git a/drivers/media/video/mt9v022.c b/drivers/media/video/mt9v022.c index b6a29f7..c5c67ec 100644 --- a/drivers/media/video/mt9v022.c +++ b/drivers/media/video/mt9v022.c @@ -129,14 +129,13 @@ static struct mt9v022 *to_mt9v022(const struct i2c_client *client) static int reg_read(struct i2c_client *client, const u8 reg) { - s32 data = i2c_smbus_read_word_data(client, reg); - return data < 0 ? data : swab16(data); + return i2c_smbus_read_word_swapped(client, reg); } static int reg_write(struct i2c_client *client, const u8 reg, const u16 data) { - return i2c_smbus_write_word_data(client, reg, swab16(data)); + return i2c_smbus_write_word_swapped(client, reg, data); } static int reg_set(struct i2c_client *client, const u8 reg, diff --git a/drivers/media/video/mt9v032.c b/drivers/media/video/mt9v032.c index c64e1dc..7906929 100644 --- a/drivers/media/video/mt9v032.c +++ b/drivers/media/video/mt9v032.c @@ -138,10 +138,10 @@ static struct mt9v032 *to_mt9v032(struct v4l2_subdev *sd) static int mt9v032_read(struct i2c_client *client, const u8 reg) { - s32 data = i2c_smbus_read_word_data(client, reg); + s32 data = i2c_smbus_read_word_swapped(client, reg); dev_dbg(&client->dev, "%s: read 0x%04x from 0x%02x\n", __func__, - swab16(data), reg); - return data < 0 ? data : swab16(data); + data, reg); + return data; } static int mt9v032_write(struct i2c_client *client, const u8 reg, @@ -149,7 +149,7 @@ static int mt9v032_write(struct i2c_client *client, const u8 reg, { dev_dbg(&client->dev, "%s: writing 0x%04x to 0x%02x\n", __func__, data, reg); - return i2c_smbus_write_word_data(client, reg, swab16(data)); + return i2c_smbus_write_word_swapped(client, reg, data); } static int mt9v032_set_chip_control(struct mt9v032 *mt9v032, u16 clear, u16 set) -- cgit v0.10.2 From d06db7ec908869cbf79829b8cbd9a04a7c802905 Mon Sep 17 00:00:00 2001 From: Archit Taneja Date: Wed, 28 Sep 2011 10:49:24 -0300 Subject: [media] OMAP_VOUT: Fix check in reqbuf for buf_size allocation The commit 383e4f69879d11c86ebdd38b3356f6d0690fb4cc makes reqbuf prevent requesting a larger size buffer than what is allocated at kernel boot during omap_vout_probe. In omap_vout_buffer_setup callback API, the requested size is compared with vout->buffer_size, this isn't correct as vout->buffer_size is later set to the size requested in reqbuf. When the video device is opened the next time, this check will prevent us to allocate a buffer which is larger than what we requested the last time. Don't use vout->buffer_size, always check with the parameters video1_bufsize or video2_bufsize. Signed-off-by: Archit Taneja Acked-by: Vaibhav Hiremath Signed-off-by: Vaibhav Hiremath Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/omap/omap_vout.c b/drivers/media/video/omap/omap_vout.c index 9c5c19f..11f5638 100644 --- a/drivers/media/video/omap/omap_vout.c +++ b/drivers/media/video/omap/omap_vout.c @@ -663,10 +663,14 @@ static int omap_vout_buffer_setup(struct videobuf_queue *q, unsigned int *count, u32 phy_addr = 0, virt_addr = 0; struct omap_vout_device *vout = q->priv_data; struct omapvideo_info *ovid = &vout->vid_info; + int vid_max_buf_size; if (!vout) return -EINVAL; + vid_max_buf_size = vout->vid == OMAP_VIDEO1 ? video1_bufsize : + video2_bufsize; + if (V4L2_BUF_TYPE_VIDEO_OUTPUT != q->type) return -EINVAL; @@ -689,7 +693,7 @@ static int omap_vout_buffer_setup(struct videobuf_queue *q, unsigned int *count, video1_numbuffers : video2_numbuffers; /* Check the size of the buffer */ - if (*size > vout->buffer_size) { + if (*size > vid_max_buf_size) { v4l2_err(&vout->vid_dev->v4l2_dev, "buffer allocation mismatch [%u] [%u]\n", *size, vout->buffer_size); -- cgit v0.10.2 From 2780168859645353086b98492a979ae97da0a2dc Mon Sep 17 00:00:00 2001 From: Archit Taneja Date: Wed, 28 Sep 2011 10:49:25 -0300 Subject: [media] OMAP_VOUT: CLEANUP: Remove redundant code from omap_vout_isr Currently, there is a lot of redundant code is between DPI and VENC panels, this can be made common by moving out field/interlace specific code to a separate function called omapvid_handle_interlace_display(). There is no functional change made. Signed-off-by: Archit Taneja Reviewed-by: Sumit Semwal Acked-by: Vaibhav Hiremath Signed-off-by: Vaibhav Hiremath Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/omap/omap_vout.c b/drivers/media/video/omap/omap_vout.c index 11f5638..7bfe577 100644 --- a/drivers/media/video/omap/omap_vout.c +++ b/drivers/media/video/omap/omap_vout.c @@ -523,10 +523,50 @@ static int omapvid_apply_changes(struct omap_vout_device *vout) return 0; } +static int omapvid_handle_interlace_display(struct omap_vout_device *vout, + unsigned int irqstatus, struct timeval timevalue) +{ + u32 fid; + + if (vout->first_int) { + vout->first_int = 0; + goto err; + } + + if (irqstatus & DISPC_IRQ_EVSYNC_ODD) + fid = 1; + else if (irqstatus & DISPC_IRQ_EVSYNC_EVEN) + fid = 0; + else + goto err; + + vout->field_id ^= 1; + if (fid != vout->field_id) { + if (fid == 0) + vout->field_id = fid; + } else if (0 == fid) { + if (vout->cur_frm == vout->next_frm) + goto err; + + vout->cur_frm->ts = timevalue; + vout->cur_frm->state = VIDEOBUF_DONE; + wake_up_interruptible(&vout->cur_frm->done); + vout->cur_frm = vout->next_frm; + } else { + if (list_empty(&vout->dma_queue) || + (vout->cur_frm != vout->next_frm)) + goto err; + } + + return vout->field_id; +err: + return 0; +} + static void omap_vout_isr(void *arg, unsigned int irqstatus) { - int ret; - u32 addr, fid; + int ret, fid; + u32 addr; struct omap_overlay *ovl; struct timeval timevalue; struct omapvideo_info *ovid; @@ -547,107 +587,59 @@ static void omap_vout_isr(void *arg, unsigned int irqstatus) spin_lock(&vout->vbq_lock); do_gettimeofday(&timevalue); - if (cur_display->type != OMAP_DISPLAY_TYPE_VENC) { - switch (cur_display->type) { - case OMAP_DISPLAY_TYPE_DPI: - if (!(irqstatus & (DISPC_IRQ_VSYNC | DISPC_IRQ_VSYNC2))) - goto vout_isr_err; - break; - case OMAP_DISPLAY_TYPE_HDMI: - if (!(irqstatus & DISPC_IRQ_EVSYNC_EVEN)) - goto vout_isr_err; - break; - default: + switch (cur_display->type) { + case OMAP_DISPLAY_TYPE_DPI: + if (!(irqstatus & (DISPC_IRQ_VSYNC | DISPC_IRQ_VSYNC2))) goto vout_isr_err; - } - if (!vout->first_int && (vout->cur_frm != vout->next_frm)) { - vout->cur_frm->ts = timevalue; - vout->cur_frm->state = VIDEOBUF_DONE; - wake_up_interruptible(&vout->cur_frm->done); - vout->cur_frm = vout->next_frm; - } - vout->first_int = 0; - if (list_empty(&vout->dma_queue)) + break; + case OMAP_DISPLAY_TYPE_VENC: + fid = omapvid_handle_interlace_display(vout, irqstatus, + timevalue); + if (!fid) goto vout_isr_err; + break; + case OMAP_DISPLAY_TYPE_HDMI: + if (!(irqstatus & DISPC_IRQ_EVSYNC_EVEN)) + goto vout_isr_err; + break; + default: + goto vout_isr_err; + } - vout->next_frm = list_entry(vout->dma_queue.next, - struct videobuf_buffer, queue); - list_del(&vout->next_frm->queue); - - vout->next_frm->state = VIDEOBUF_ACTIVE; - - addr = (unsigned long) vout->queued_buf_addr[vout->next_frm->i] - + vout->cropped_offset; + if (!vout->first_int && (vout->cur_frm != vout->next_frm)) { + vout->cur_frm->ts = timevalue; + vout->cur_frm->state = VIDEOBUF_DONE; + wake_up_interruptible(&vout->cur_frm->done); + vout->cur_frm = vout->next_frm; + } - /* First save the configuration in ovelray structure */ - ret = omapvid_init(vout, addr); - if (ret) - printk(KERN_ERR VOUT_NAME - "failed to set overlay info\n"); - /* Enable the pipeline and set the Go bit */ - ret = omapvid_apply_changes(vout); - if (ret) - printk(KERN_ERR VOUT_NAME "failed to change mode\n"); - } else { + vout->first_int = 0; + if (list_empty(&vout->dma_queue)) + goto vout_isr_err; - if (vout->first_int) { - vout->first_int = 0; - goto vout_isr_err; - } - if (irqstatus & DISPC_IRQ_EVSYNC_ODD) - fid = 1; - else if (irqstatus & DISPC_IRQ_EVSYNC_EVEN) - fid = 0; - else - goto vout_isr_err; + vout->next_frm = list_entry(vout->dma_queue.next, + struct videobuf_buffer, queue); + list_del(&vout->next_frm->queue); - vout->field_id ^= 1; - if (fid != vout->field_id) { - if (0 == fid) - vout->field_id = fid; + vout->next_frm->state = VIDEOBUF_ACTIVE; - goto vout_isr_err; - } - if (0 == fid) { - if (vout->cur_frm == vout->next_frm) - goto vout_isr_err; - - vout->cur_frm->ts = timevalue; - vout->cur_frm->state = VIDEOBUF_DONE; - wake_up_interruptible(&vout->cur_frm->done); - vout->cur_frm = vout->next_frm; - } else if (1 == fid) { - if (list_empty(&vout->dma_queue) || - (vout->cur_frm != vout->next_frm)) - goto vout_isr_err; - - vout->next_frm = list_entry(vout->dma_queue.next, - struct videobuf_buffer, queue); - list_del(&vout->next_frm->queue); - - vout->next_frm->state = VIDEOBUF_ACTIVE; - addr = (unsigned long) - vout->queued_buf_addr[vout->next_frm->i] + - vout->cropped_offset; - /* First save the configuration in ovelray structure */ - ret = omapvid_init(vout, addr); - if (ret) - printk(KERN_ERR VOUT_NAME - "failed to set overlay info\n"); - /* Enable the pipeline and set the Go bit */ - ret = omapvid_apply_changes(vout); - if (ret) - printk(KERN_ERR VOUT_NAME - "failed to change mode\n"); - } + addr = (unsigned long) vout->queued_buf_addr[vout->next_frm->i] + + vout->cropped_offset; - } + /* First save the configuration in ovelray structure */ + ret = omapvid_init(vout, addr); + if (ret) + printk(KERN_ERR VOUT_NAME + "failed to set overlay info\n"); + /* Enable the pipeline and set the Go bit */ + ret = omapvid_apply_changes(vout); + if (ret) + printk(KERN_ERR VOUT_NAME "failed to change mode\n"); vout_isr_err: spin_unlock(&vout->vbq_lock); } - /* Video buffer call backs */ /* -- cgit v0.10.2 From e144ca6426655aec8ec828e339ac57a3e00fefd0 Mon Sep 17 00:00:00 2001 From: Archit Taneja Date: Wed, 28 Sep 2011 10:49:26 -0300 Subject: [media] OMAP_VOUT: Fix VSYNC IRQ handling in omap_vout_isr Currently, in omap_vout_isr(), if the panel type is DPI, and if we get either VSYNC or VSYNC2 interrupts, we proceed ahead to set the current buffers state to VIDEOBUF_DONE and prepare to display the next frame in the queue. On OMAP4, because we have 2 LCD managers, the panel type itself is not sufficient to tell if we have received the correct irq, i.e, we shouldn't proceed ahead if we get a VSYNC interrupt for LCD2 manager, or a VSYNC2 interrupt for LCD manager. Fix this by correlating LCD manager to VSYNC interrupt and LCD2 manager to VSYNC2 interrupt. Signed-off-by: Archit Taneja Reviewed-by: Sumit Semwal Acked-by: Vaibhav Hiremath Signed-off-by: Vaibhav Hiremath Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/omap/omap_vout.c b/drivers/media/video/omap/omap_vout.c index 7bfe577..c344d59 100644 --- a/drivers/media/video/omap/omap_vout.c +++ b/drivers/media/video/omap/omap_vout.c @@ -565,8 +565,8 @@ err: static void omap_vout_isr(void *arg, unsigned int irqstatus) { - int ret, fid; - u32 addr; + int ret, fid, mgr_id; + u32 addr, irq; struct omap_overlay *ovl; struct timeval timevalue; struct omapvideo_info *ovid; @@ -582,6 +582,7 @@ static void omap_vout_isr(void *arg, unsigned int irqstatus) if (!ovl->manager || !ovl->manager->device) return; + mgr_id = ovl->manager->id; cur_display = ovl->manager->device; spin_lock(&vout->vbq_lock); @@ -589,7 +590,14 @@ static void omap_vout_isr(void *arg, unsigned int irqstatus) switch (cur_display->type) { case OMAP_DISPLAY_TYPE_DPI: - if (!(irqstatus & (DISPC_IRQ_VSYNC | DISPC_IRQ_VSYNC2))) + if (mgr_id == OMAP_DSS_CHANNEL_LCD) + irq = DISPC_IRQ_VSYNC; + else if (mgr_id == OMAP_DSS_CHANNEL_LCD2) + irq = DISPC_IRQ_VSYNC2; + else + goto vout_isr_err; + + if (!(irqstatus & irq)) goto vout_isr_err; break; case OMAP_DISPLAY_TYPE_VENC: -- cgit v0.10.2 From 881a9640112f89fbe2ffdcec2b06ab163739595f Mon Sep 17 00:00:00 2001 From: Archit Taneja Date: Wed, 28 Sep 2011 10:49:27 -0300 Subject: [media] OMAP_VOUT: Add support for DSI panels Add support for DSI panels. DSI video mode panels will work directly. For command mode panels, we will need to trigger updates regularly. This isn't done by the omap_vout driver currently. It can still be supported if we connect a framebuffer device to the panel and configure it in auto update mode. Signed-off-by: Archit Taneja Acked-by: Vaibhav Hiremath Signed-off-by: Vaibhav Hiremath Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/omap/omap_vout.c b/drivers/media/video/omap/omap_vout.c index c344d59..def6472 100644 --- a/drivers/media/video/omap/omap_vout.c +++ b/drivers/media/video/omap/omap_vout.c @@ -589,6 +589,7 @@ static void omap_vout_isr(void *arg, unsigned int irqstatus) do_gettimeofday(&timevalue); switch (cur_display->type) { + case OMAP_DISPLAY_TYPE_DSI: case OMAP_DISPLAY_TYPE_DPI: if (mgr_id == OMAP_DSS_CHANNEL_LCD) irq = DISPC_IRQ_VSYNC; -- cgit v0.10.2 From cfb128ed0768320c2d0e43cf781c8eaa622876b6 Mon Sep 17 00:00:00 2001 From: Archit Taneja Date: Wed, 28 Sep 2011 10:49:28 -0300 Subject: [media] OMAP_VOUT: Increase MAX_DISPLAYS to a larger value There is no limit to the number of displays that can registered with DSS2. The current value of MAX_DISPLAYS is 3, set this to 10 so that the 'displays' member of omap2video_device struct can store more omap_dss_device pointers. This fixes a crash seen in omap_vout_probe when DSS2 registers for more than 3 displays. Signed-off-by: Archit Taneja Acked-by: Vaibhav Hiremath Signed-off-by: Vaibhav Hiremath Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/omap/omap_voutdef.h b/drivers/media/video/omap/omap_voutdef.h index d793501..27a95d2 100644 --- a/drivers/media/video/omap/omap_voutdef.h +++ b/drivers/media/video/omap/omap_voutdef.h @@ -25,7 +25,7 @@ #define MAC_VRFB_CTXS 4 #define MAX_VOUT_DEV 2 #define MAX_OVLS 3 -#define MAX_DISPLAYS 3 +#define MAX_DISPLAYS 10 #define MAX_MANAGERS 3 #define QQVGA_WIDTH 160 -- cgit v0.10.2 From c27e3050378ec0d96d964cbf18746a30ad00ab9f Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Sat, 22 Oct 2011 04:57:54 -0300 Subject: [media] v4l: mt9p031/mt9t001: Use i2c_smbus_{read|write}_word_swapped() The MT9P031 and MT9T001 sensors transfer 16-bit data on the I2C bus in swapped order. Let the I2C core handle byte order by using the i2c_smbus_{read|write}_word_swapped() functions. Signed-off-by: Laurent Pinchart Acked-by: Jonathan Cameron Acked-by: Jean Delvare Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/mt9p031.c b/drivers/media/video/mt9p031.c index 73c0689..93c3ec7 100644 --- a/drivers/media/video/mt9p031.c +++ b/drivers/media/video/mt9p031.c @@ -132,13 +132,12 @@ static struct mt9p031 *to_mt9p031(struct v4l2_subdev *sd) static int mt9p031_read(struct i2c_client *client, u8 reg) { - s32 data = i2c_smbus_read_word_data(client, reg); - return data < 0 ? data : be16_to_cpu(data); + return i2c_smbus_read_word_swapped(client, reg); } static int mt9p031_write(struct i2c_client *client, u8 reg, u16 data) { - return i2c_smbus_write_word_data(client, reg, cpu_to_be16(data)); + return i2c_smbus_write_word_swapped(client, reg, data); } static int mt9p031_set_output_control(struct mt9p031 *mt9p031, u16 clear, diff --git a/drivers/media/video/mt9t001.c b/drivers/media/video/mt9t001.c index 08074b8..cd81d04a 100644 --- a/drivers/media/video/mt9t001.c +++ b/drivers/media/video/mt9t001.c @@ -133,13 +133,12 @@ static inline struct mt9t001 *to_mt9t001(struct v4l2_subdev *sd) static int mt9t001_read(struct i2c_client *client, u8 reg) { - s32 data = i2c_smbus_read_word_data(client, reg); - return data < 0 ? data : be16_to_cpu(data); + return i2c_smbus_read_word_swapped(client, reg); } static int mt9t001_write(struct i2c_client *client, u8 reg, u16 data) { - return i2c_smbus_write_word_data(client, reg, cpu_to_be16(data)); + return i2c_smbus_write_word_swapped(client, reg, data); } static int mt9t001_set_output_control(struct mt9t001 *mt9t001, u16 clear, -- cgit v0.10.2 From a61f96bc3abccc8b41e422da8e808eb685527305 Mon Sep 17 00:00:00 2001 From: sensoray-dev Date: Mon, 24 Oct 2011 19:46:52 -0300 Subject: [media] saa7134: adding Sensoray boards to saa7134 driver commit cf5886c3dd2f65c817cb6ca5e7202fa3a3bdc872 Signed-off-by: Dean Anderson Signed-off-by: Mauro Carvalho Chehab diff --git a/Documentation/video4linux/CARDLIST.saa7134 b/Documentation/video4linux/CARDLIST.saa7134 index 7efae9b..e7ef38a 100644 --- a/Documentation/video4linux/CARDLIST.saa7134 +++ b/Documentation/video4linux/CARDLIST.saa7134 @@ -186,3 +186,4 @@ 185 -> MagicPro ProHDTV Pro2 DMB-TH/Hybrid [17de:d136] 186 -> Beholder BeholdTV 501 [5ace:5010] 187 -> Beholder BeholdTV 503 FM [5ace:5030] +188 -> Sensoray 811/911 [6000:0811,6000:0911] diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c index 0f9fb99..065d0f6 100644 --- a/drivers/media/video/saa7134/saa7134-cards.c +++ b/drivers/media/video/saa7134/saa7134-cards.c @@ -5691,6 +5691,27 @@ struct saa7134_board saa7134_boards[] = { .amux = LINE1, }, }, + [SAA7134_BOARD_SENSORAY811_911] = { + .name = "Sensoray 811/911", + .audio_clock = 0x00200000, + .tuner_type = TUNER_ABSENT, + .radio_type = UNSET, + .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, + .inputs = {{ + .name = name_comp1, + .vmux = 0, + .amux = LINE1, + }, { + .name = name_comp3, + .vmux = 2, + .amux = LINE1, + }, { + .name = name_svideo, + .vmux = 8, + .amux = LINE1, + } }, + }, }; @@ -6914,6 +6935,18 @@ struct pci_device_id saa7134_pci_tbl[] = { .subdevice = 0xd136, .driver_data = SAA7134_BOARD_MAGICPRO_PROHDTV_PRO2, }, { + .vendor = PCI_VENDOR_ID_PHILIPS, + .device = PCI_DEVICE_ID_PHILIPS_SAA7133, + .subvendor = 0x6000, + .subdevice = 0x0811, + .driver_data = SAA7134_BOARD_SENSORAY811_911, + }, { + .vendor = PCI_VENDOR_ID_PHILIPS, + .device = PCI_DEVICE_ID_PHILIPS_SAA7133, + .subvendor = 0x6000, + .subdevice = 0x0911, + .driver_data = SAA7134_BOARD_SENSORAY811_911, + }, { /* --- boards without eeprom + subsystem ID --- */ .vendor = PCI_VENDOR_ID_PHILIPS, .device = PCI_DEVICE_ID_PHILIPS_SAA7134, diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h index 9b55068..4ad9de4 100644 --- a/drivers/media/video/saa7134/saa7134.h +++ b/drivers/media/video/saa7134/saa7134.h @@ -330,6 +330,7 @@ struct saa7134_card_ir { #define SAA7134_BOARD_MAGICPRO_PROHDTV_PRO2 185 #define SAA7134_BOARD_BEHOLD_501 186 #define SAA7134_BOARD_BEHOLD_503FM 187 +#define SAA7134_BOARD_SENSORAY811_911 188 #define SAA7134_MAXBOARDS 32 #define SAA7134_INPUT_MAX 8 -- cgit v0.10.2 From 57437c1da54e5cf7d536d72d61e77ebeb528a87d Mon Sep 17 00:00:00 2001 From: sensoray-dev Date: Tue, 25 Oct 2011 19:43:55 -0300 Subject: [media] bttv: adding Sensoray 611 board to driver commit affebd4db94b459f676a14d9bb696c3c2b73643d [media] bttv: adding Sensoray 611 board to bttv driver Signed-off-by: Dean Anderson Signed-off-by: Mauro Carvalho Chehab diff --git a/Documentation/video4linux/CARDLIST.bttv b/Documentation/video4linux/CARDLIST.bttv index 4739d56..8948da4 100644 --- a/Documentation/video4linux/CARDLIST.bttv +++ b/Documentation/video4linux/CARDLIST.bttv @@ -71,7 +71,7 @@ 70 -> Prolink Pixelview PV-BT878P+ (Rev.4C,8E) 71 -> Lifeview FlyVideo 98EZ (capture only) LR51 [1851:1851] 72 -> Prolink Pixelview PV-BT878P+9B (PlayTV Pro rev.9B FM+NICAM) [1554:4011] - 73 -> Sensoray 311 [6000:0311] + 73 -> Sensoray 311/611 [6000:0311,6000:0611] 74 -> RemoteVision MX (RV605) 75 -> Powercolor MTV878/ MTV878R/ MTV878F 76 -> Canopus WinDVR PCI (COMPAQ Presario 3524JP, 5112JP) [0e11:0079] diff --git a/drivers/media/video/bt8xx/bttv-cards.c b/drivers/media/video/bt8xx/bttv-cards.c index 5939021..076b7f2 100644 --- a/drivers/media/video/bt8xx/bttv-cards.c +++ b/drivers/media/video/bt8xx/bttv-cards.c @@ -284,7 +284,8 @@ static struct CARD { { 0x10b42636, BTTV_BOARD_HAUPPAUGE878, "STB ???" }, { 0x217d6606, BTTV_BOARD_WINFAST2000, "Leadtek WinFast TV 2000" }, { 0xfff6f6ff, BTTV_BOARD_WINFAST2000, "Leadtek WinFast TV 2000" }, - { 0x03116000, BTTV_BOARD_SENSORAY311, "Sensoray 311" }, + { 0x03116000, BTTV_BOARD_SENSORAY311_611, "Sensoray 311" }, + { 0x06116000, BTTV_BOARD_SENSORAY311_611, "Sensoray 611" }, { 0x00790e11, BTTV_BOARD_WINDVR, "Canopus WinDVR PCI" }, { 0xa0fca1a0, BTTV_BOARD_ZOLTRIX, "Face to Face Tvmax" }, { 0x82b2aa6a, BTTV_BOARD_SIMUS_GVC1100, "SIMUS GVC1100" }, @@ -1526,10 +1527,10 @@ struct tvcard bttv_tvcards[] = { GPIO20,22,23: R30,R29,R28 */ }, - [BTTV_BOARD_SENSORAY311] = { + [BTTV_BOARD_SENSORAY311_611] = { /* Clay Kunz */ - /* you must jumper JP5 for the card to work */ - .name = "Sensoray 311", + /* you must jumper JP5 for the 311 card (PC/104+) to work */ + .name = "Sensoray 311/611", .video_inputs = 5, /* .audio_inputs= 0, */ .svhs = 4, diff --git a/drivers/media/video/bt8xx/bttv.h b/drivers/media/video/bt8xx/bttv.h index c633359..4db8b7d 100644 --- a/drivers/media/video/bt8xx/bttv.h +++ b/drivers/media/video/bt8xx/bttv.h @@ -96,7 +96,7 @@ #define BTTV_BOARD_PV_BT878P_PLUS 0x46 #define BTTV_BOARD_FLYVIDEO98EZ 0x47 #define BTTV_BOARD_PV_BT878P_9B 0x48 -#define BTTV_BOARD_SENSORAY311 0x49 +#define BTTV_BOARD_SENSORAY311_611 0x49 #define BTTV_BOARD_RV605 0x4a #define BTTV_BOARD_POWERCLR_MTV878 0x4b #define BTTV_BOARD_WINDVR 0x4c -- cgit v0.10.2 From 318cde38af41fefdd03a7e42c9fb70e9719ed83f Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 7 Nov 2011 12:01:49 -0200 Subject: [media] Update some CARDLIST's Re-run the cardlist script, in order to update the cardlists for a few drivers, to sync with the driver changes. Signed-off-by: Mauro Carvalho Chehab diff --git a/Documentation/video4linux/CARDLIST.cx23885 b/Documentation/video4linux/CARDLIST.cx23885 index 8910449..99acaa3 100644 --- a/Documentation/video4linux/CARDLIST.cx23885 +++ b/Documentation/video4linux/CARDLIST.cx23885 @@ -29,3 +29,5 @@ 28 -> LEADTEK WinFast PxTV1200 [107d:6f22] 29 -> GoTView X5 3D Hybrid [5654:2390] 30 -> NetUP Dual DVB-T/C-CI RF [1b55:e2e4] + 31 -> Leadtek Winfast PxDVR3200 H XC4000 [107d:6f39] + 32 -> MPX-885 diff --git a/Documentation/video4linux/CARDLIST.cx88 b/Documentation/video4linux/CARDLIST.cx88 index d9c0f11..eee18e6 100644 --- a/Documentation/video4linux/CARDLIST.cx88 +++ b/Documentation/video4linux/CARDLIST.cx88 @@ -85,3 +85,5 @@ 84 -> Samsung SMT 7020 DVB-S [18ac:dc00,18ac:dccd] 85 -> Twinhan VP-1027 DVB-S [1822:0023] 86 -> TeVii S464 DVB-S/S2 [d464:9022] + 87 -> Leadtek WinFast DTV2000 H PLUS [107d:6f42] + 88 -> Leadtek WinFast DTV1800 H (XC4000) [107d:6f38] diff --git a/Documentation/video4linux/CARDLIST.em28xx b/Documentation/video4linux/CARDLIST.em28xx index 4a7b3df..d8c8544 100644 --- a/Documentation/video4linux/CARDLIST.em28xx +++ b/Documentation/video4linux/CARDLIST.em28xx @@ -11,7 +11,7 @@ 10 -> Hauppauge WinTV HVR 900 (em2880) [2040:6500] 11 -> Terratec Hybrid XS (em2880) 12 -> Kworld PVR TV 2800 RF (em2820/em2840) - 13 -> Terratec Prodigy XS (em2880) [0ccd:0047] + 13 -> Terratec Prodigy XS (em2880) [0ccd:10ad] 14 -> SIIG AVTuner-PVR / Pixelview Prolink PlayTV USB 2.0 (em2820/em2840) 15 -> V-Gear PocketTV (em2800) 16 -> Hauppauge WinTV HVR 950 (em2883) [2040:6513,2040:6517,2040:651b] @@ -41,7 +41,7 @@ 40 -> Plextor ConvertX PX-TV100U (em2861) [093b:a005] 41 -> Kworld 350 U DVB-T (em2870) [eb1a:e350] 42 -> Kworld 355 U DVB-T (em2870) [eb1a:e355,eb1a:e357] - 43 -> Terratec Cinergy T XS (em2870) [0ccd:0043] + 43 -> Terratec Cinergy T XS (em2870) 44 -> Terratec Cinergy T XS (MT2060) (em2870) 45 -> Pinnacle PCTV DVB-T (em2870) 46 -> Compro, VideoMate U3 (em2870) [185b:2870] @@ -64,7 +64,7 @@ 64 -> Easy Cap Capture DC-60 (em2860) 65 -> IO-DATA GV-MVP/SZ (em2820/em2840) [04bb:0515] 66 -> Empire dual TV (em2880) - 67 -> Terratec Grabby (em2860) [0ccd:0096] + 67 -> Terratec Grabby (em2860) [0ccd:0096,0ccd:10AF] 68 -> Terratec AV350 (em2860) [0ccd:0084] 69 -> KWorld ATSC 315U HDTV TV Box (em2882) [eb1a:a313] 70 -> Evga inDtube (em2882) @@ -76,3 +76,5 @@ 76 -> KWorld PlusTV 340U or UB435-Q (ATSC) (em2870) [1b80:a340] 77 -> EM2874 Leadership ISDBT (em2874) 78 -> PCTV nanoStick T2 290e (em28174) + 79 -> Terratec Cinergy H5 (em2884) [0ccd:0043,0ccd:10a2] + 80 -> PCTV DVB-S2 Stick (460e) (em28174) diff --git a/Documentation/video4linux/CARDLIST.saa7164 b/Documentation/video4linux/CARDLIST.saa7164 index 152bd7b..2205e8d 100644 --- a/Documentation/video4linux/CARDLIST.saa7164 +++ b/Documentation/video4linux/CARDLIST.saa7164 @@ -7,3 +7,5 @@ 6 -> Hauppauge WinTV-HVR2200 [0070:8901] 7 -> Hauppauge WinTV-HVR2250 [0070:8891,0070:8851] 8 -> Hauppauge WinTV-HVR2250 [0070:88A1] + 9 -> Hauppauge WinTV-HVR2200 [0070:8940] + 10 -> Hauppauge WinTV-HVR2200 [0070:8953] -- cgit v0.10.2 From 9c900f02385cb18e1a6c65d22a7acbb8c73c07c2 Mon Sep 17 00:00:00 2001 From: Daniel Drake Date: Wed, 26 Oct 2011 09:16:50 -0300 Subject: [media] via-camera: disable RGB mode The RGB mode does not work correctly. It captures fine at 640x480 but whenever the scaling engine is used to produce another resolution, color corruption occurs (lots of erroneous pink and green). It is not clear how the scaling engine is supposed to work and how it knows which pixel format it is dealing with. Work around this problem by disabling RGB support. YUYV scaling works just fine. Test case: gst-launch v4l2src ! video/x-raw-rgb,bpp=16,width=320,height=240 ! \ ffmpegcolorspace ! xvimagesink Signed-off-by: Daniel Drake Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/via-camera.c b/drivers/media/video/via-camera.c index cbf13d0..6a82875 100644 --- a/drivers/media/video/via-camera.c +++ b/drivers/media/video/via-camera.c @@ -156,14 +156,10 @@ static struct via_format { .mbus_code = V4L2_MBUS_FMT_YUYV8_2X8, .bpp = 2, }, - { - .desc = "RGB 565", - .pixelformat = V4L2_PIX_FMT_RGB565, - .mbus_code = V4L2_MBUS_FMT_RGB565_2X8_LE, - .bpp = 2, - }, /* RGB444 and Bayer should be doable, but have never been - tested with this driver. */ + tested with this driver. RGB565 seems to work at the default + resolution, but results in color corruption when being scaled by + viacam_set_scaled(), and is disabled as a result. */ }; #define N_VIA_FMTS ARRAY_SIZE(via_formats) -- cgit v0.10.2 From fabade547fd306cd3e8b1dc068ccdfec2553bad5 Mon Sep 17 00:00:00 2001 From: Dmitri Belimov Date: Thu, 23 Apr 2009 01:40:46 -0300 Subject: [media] FM1216ME_MK3 AUX byte for FM mode Write AUX byte to FM1216ME_MK3 when FM mode, better sensitivity. It can be usefull for other tuners. Signed-off-by: Beholder Intl. Ltd. Dmitry Belimov Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/common/tuners/tuner-simple.c b/drivers/media/common/tuners/tuner-simple.c index f8ee29e..4092200 100644 --- a/drivers/media/common/tuners/tuner-simple.c +++ b/drivers/media/common/tuners/tuner-simple.c @@ -751,6 +751,17 @@ static int simple_set_radio_freq(struct dvb_frontend *fe, if (4 != rc) tuner_warn("i2c i/o error: rc == %d (should be 4)\n", rc); + /* Write AUX byte */ + switch (priv->type) { + case TUNER_PHILIPS_FM1216ME_MK3: + buffer[2] = 0x98; + buffer[3] = 0x20; /* set TOP AGC */ + rc = tuner_i2c_xfer_send(&priv->i2c_props, buffer, 4); + if (4 != rc) + tuner_warn("i2c i/o error: rc == %d (should be 4)\n", rc); + break; + } + return 0; } -- cgit v0.10.2 From 0d37d35035cb41f01e12082fa6b39a2e465ca4ba Mon Sep 17 00:00:00 2001 From: Christian Gmeiner Date: Thu, 27 Oct 2011 18:50:21 -0300 Subject: [media] Make use of media bus pixel codes in adv7170 driver MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The ADV7170/ADV7171 can operate in either 8-bit or 16-bit YCrCb Mode. * 8-Bit YCrCb Mode This default mode accepts multiplexed YCrCb inputs through the P7-P0 pixel inputs. The inputs follow the sequence Cb0, Y0 Cr0, Y1 Cb1, Y2, etc. The Y, Cb and Cr data are input on a rising clock edge. * 16-Bit YCrCb Mode This mode accepts Y inputs through the P7–P0 pixel inputs and multiplexed CrCb inputs through the P15–P8 pixel inputs. The data is loaded on every second rising edge of CLOCK. The inputs follow the sequence Cb0, Y0 Cr0, Y1 Cb1, Y2, etc. Signed-off-by: Christian Gmeiner Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/adv7170.c b/drivers/media/video/adv7170.c index 23ba5c3..879f1d8 100644 --- a/drivers/media/video/adv7170.c +++ b/drivers/media/video/adv7170.c @@ -64,6 +64,11 @@ static inline struct adv7170 *to_adv7170(struct v4l2_subdev *sd) static char *inputs[] = { "pass_through", "play_back" }; +static enum v4l2_mbus_pixelcode adv7170_codes[] = { + V4L2_MBUS_FMT_UYVY8_2X8, + V4L2_MBUS_FMT_UYVY8_1X16, +}; + /* ----------------------------------------------------------------------- */ static inline int adv7170_write(struct v4l2_subdev *sd, u8 reg, u8 value) @@ -258,6 +263,60 @@ static int adv7170_s_routing(struct v4l2_subdev *sd, return 0; } +static int adv7170_enum_fmt(struct v4l2_subdev *sd, unsigned int index, + enum v4l2_mbus_pixelcode *code) +{ + if (index >= ARRAY_SIZE(adv7170_codes)) + return -EINVAL; + + *code = adv7170_codes[index]; + return 0; +} + +static int adv7170_g_fmt(struct v4l2_subdev *sd, + struct v4l2_mbus_framefmt *mf) +{ + u8 val = adv7170_read(sd, 0x7); + + if ((val & 0x40) == (1 << 6)) + mf->code = V4L2_MBUS_FMT_UYVY8_1X16; + else + mf->code = V4L2_MBUS_FMT_UYVY8_2X8; + + mf->colorspace = V4L2_COLORSPACE_SMPTE170M; + mf->width = 0; + mf->height = 0; + mf->field = V4L2_FIELD_ANY; + + return 0; +} + +static int adv7170_s_fmt(struct v4l2_subdev *sd, + struct v4l2_mbus_framefmt *mf) +{ + u8 val = adv7170_read(sd, 0x7); + int ret; + + switch (mf->code) { + case V4L2_MBUS_FMT_UYVY8_2X8: + val &= ~0x40; + break; + + case V4L2_MBUS_FMT_UYVY8_1X16: + val |= 0x40; + break; + + default: + v4l2_dbg(1, debug, sd, + "illegal v4l2_mbus_framefmt code: %d\n", mf->code); + return -EINVAL; + } + + ret = adv7170_write(sd, 0x7, val); + + return ret; +} + static int adv7170_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip) { struct i2c_client *client = v4l2_get_subdevdata(sd); @@ -274,6 +333,9 @@ static const struct v4l2_subdev_core_ops adv7170_core_ops = { static const struct v4l2_subdev_video_ops adv7170_video_ops = { .s_std_output = adv7170_s_std_output, .s_routing = adv7170_s_routing, + .s_mbus_fmt = adv7170_s_fmt, + .g_mbus_fmt = adv7170_g_fmt, + .enum_mbus_fmt = adv7170_enum_fmt, }; static const struct v4l2_subdev_ops adv7170_ops = { -- cgit v0.10.2 From 0a4524d726cd4d109c57fc194a55ff0a9e4df0e9 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Fri, 28 Oct 2011 19:58:16 -0300 Subject: [media] drivers/media/video/atmel-isi.c: eliminate a null pointer dereference The variable isi might be null or might be freed at the point of the call to clk_put. pclk contains the value that isi->pclk is expected to point to. The semantic match that finds this problem is as follows: // @r@ expression E, E1; identifier f; statement S1,S2,S3; @@ if (E == NULL) { ... when != if (E == NULL || ...) S1 else S2 when != E = E1 *E->f ... when any return ...; } else S3 // Signed-off-by: Julia Lawall Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/atmel-isi.c b/drivers/media/video/atmel-isi.c index 8c775c5..fbc904f 100644 --- a/drivers/media/video/atmel-isi.c +++ b/drivers/media/video/atmel-isi.c @@ -1036,7 +1036,7 @@ err_alloc_ctx: err_alloc_descriptors: kfree(isi); err_alloc_isi: - clk_put(isi->pclk); + clk_put(pclk); return ret; } -- cgit v0.10.2 From 49a0513c1fca2c43b14416f3f40220fa01ab5e39 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Fri, 28 Oct 2011 19:58:17 -0300 Subject: [media] drivers/media/video/davinci/vpbe_display.c: eliminate a null pointer dereference In the original code, probe_out could be reached when res was null and then when the irq had not yet been requested. In those cases, the call to free_irq is not needed, so move probe_out down and introduce a new label for the case where calling free_irq is useful. The semantic match that finds this problem is as follows: // @r@ expression E, E1; identifier f; statement S1,S2,S3; @@ if (E == NULL) { ... when != if (E == NULL || ...) S1 else S2 when != E = E1 *E->f ... when any return ...; } else S3 // Signed-off-by: Julia Lawall Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/davinci/vpbe_display.c b/drivers/media/video/davinci/vpbe_display.c index 8588a86..d98da4b 100644 --- a/drivers/media/video/davinci/vpbe_display.c +++ b/drivers/media/video/davinci/vpbe_display.c @@ -1746,15 +1746,16 @@ static __devinit int vpbe_display_probe(struct platform_device *pdev) for (i = 0; i < VPBE_DISPLAY_MAX_DEVICES; i++) { if (register_device(disp_dev->dev[i], disp_dev, pdev)) { err = -ENODEV; - goto probe_out; + goto probe_out_irq; } } printk(KERN_DEBUG "Successfully completed the probing of vpbe v4l2 device\n"); return 0; -probe_out: +probe_out_irq: free_irq(res->start, disp_dev); +probe_out: for (k = 0; k < VPBE_DISPLAY_MAX_DEVICES; k++) { /* Get the pointer to the layer object */ vpbe_display_layer = disp_dev->dev[k]; -- cgit v0.10.2 From 5279b1ff3699153a53d7ca030b5fb95950001c36 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Mon, 31 Oct 2011 08:11:00 -0300 Subject: [media] au8522: Calculate signal strength shown as percentage from SNR up to 35dB As done first in lgdt330x.c, calculate signal strength from SNR up to 35dB Even though the SNR can go higher than 35dB, there is some comfort factor in having a range of strong signals that can show at 100% Signed-off-by: Michael Krufky Signed-off-by: Devin Heitmueller Signed-off-by: Steven Toth Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/dvb/frontends/au8522_dig.c b/drivers/media/dvb/frontends/au8522_dig.c index 1d57294..5c0d398 100644 --- a/drivers/media/dvb/frontends/au8522_dig.c +++ b/drivers/media/dvb/frontends/au8522_dig.c @@ -862,7 +862,36 @@ static int au8522_read_snr(struct dvb_frontend *fe, u16 *snr) static int au8522_read_signal_strength(struct dvb_frontend *fe, u16 *signal_strength) { - return au8522_read_snr(fe, signal_strength); + /* borrowed from lgdt330x.c + * + * Calculate strength from SNR up to 35dB + * Even though the SNR can go higher than 35dB, + * there is some comfort factor in having a range of + * strong signals that can show at 100% + */ + u16 snr; + u32 tmp; + int ret = au8522_read_snr(fe, &snr); + + *signal_strength = 0; + + if (0 == ret) { + /* The following calculation method was chosen + * purely for the sake of code re-use from the + * other demod drivers that use this method */ + + /* Convert from SNR in dB * 10 to 8.24 fixed-point */ + tmp = (snr * ((1 << 24) / 10)); + + /* Convert from 8.24 fixed-point to + * scale the range 0 - 35*2^24 into 0 - 65535*/ + if (tmp >= 8960 * 0x10000) + *signal_strength = 0xffff; + else + *signal_strength = tmp / 8960; + } + + return ret; } static int au8522_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) -- cgit v0.10.2 From 19661c08fe11590e04832ed8b3cabe5e4bf11e48 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Mon, 31 Oct 2011 08:12:18 -0300 Subject: [media] s5h1409: Calculate signal strength shown as percentage from SNR up to 35dB As done first in lgdt330x.c, calculate signal strength from SNR up to 35dB Even though the SNR can go higher than 35dB, there is some comfort factor in having a range of strong signals that can show at 100% Signed-off-by: Michael Krufky Signed-off-by: Devin Heitmueller Signed-off-by: Steven Toth Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/dvb/frontends/s5h1409.c b/drivers/media/dvb/frontends/s5h1409.c index 0e2f61a..0d6d5e3 100644 --- a/drivers/media/dvb/frontends/s5h1409.c +++ b/drivers/media/dvb/frontends/s5h1409.c @@ -879,7 +879,36 @@ static int s5h1409_read_snr(struct dvb_frontend *fe, u16 *snr) static int s5h1409_read_signal_strength(struct dvb_frontend *fe, u16 *signal_strength) { - return s5h1409_read_snr(fe, signal_strength); + /* borrowed from lgdt330x.c + * + * Calculate strength from SNR up to 35dB + * Even though the SNR can go higher than 35dB, + * there is some comfort factor in having a range of + * strong signals that can show at 100% + */ + u16 snr; + u32 tmp; + int ret = s5h1409_read_snr(fe, &snr); + + *signal_strength = 0; + + if (0 == ret) { + /* The following calculation method was chosen + * purely for the sake of code re-use from the + * other demod drivers that use this method */ + + /* Convert from SNR in dB * 10 to 8.24 fixed-point */ + tmp = (snr * ((1 << 24) / 10)); + + /* Convert from 8.24 fixed-point to + * scale the range 0 - 35*2^24 into 0 - 65535*/ + if (tmp >= 8960 * 0x10000) + *signal_strength = 0xffff; + else + *signal_strength = tmp / 8960; + } + + return ret; } static int s5h1409_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) -- cgit v0.10.2 From ead32d5357e4aae732ccd7427073ab4bf30d3068 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Mon, 31 Oct 2011 08:12:54 -0300 Subject: [media] s5h1411: Calculate signal strength shown as percentage from SNR up to 35dB As done first in lgdt330x.c, calculate signal strength from SNR up to 35dB Even though the SNR can go higher than 35dB, there is some comfort factor in having a range of strong signals that can show at 100% Signed-off-by: Michael Krufky Signed-off-by: Devin Heitmueller Signed-off-by: Steven Toth Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/dvb/frontends/s5h1411.c b/drivers/media/dvb/frontends/s5h1411.c index d8adf1e..5fca113 100644 --- a/drivers/media/dvb/frontends/s5h1411.c +++ b/drivers/media/dvb/frontends/s5h1411.c @@ -794,7 +794,36 @@ static int s5h1411_read_snr(struct dvb_frontend *fe, u16 *snr) static int s5h1411_read_signal_strength(struct dvb_frontend *fe, u16 *signal_strength) { - return s5h1411_read_snr(fe, signal_strength); + /* borrowed from lgdt330x.c + * + * Calculate strength from SNR up to 35dB + * Even though the SNR can go higher than 35dB, + * there is some comfort factor in having a range of + * strong signals that can show at 100% + */ + u16 snr; + u32 tmp; + int ret = s5h1411_read_snr(fe, &snr); + + *signal_strength = 0; + + if (0 == ret) { + /* The following calculation method was chosen + * purely for the sake of code re-use from the + * other demod drivers that use this method */ + + /* Convert from SNR in dB * 10 to 8.24 fixed-point */ + tmp = (snr * ((1 << 24) / 10)); + + /* Convert from 8.24 fixed-point to + * scale the range 0 - 35*2^24 into 0 - 65535*/ + if (tmp >= 8960 * 0x10000) + *signal_strength = 0xffff; + else + *signal_strength = tmp / 8960; + } + + return ret; } static int s5h1411_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) -- cgit v0.10.2 From b7d425d39179e125604cbf451a06d3204d2e1398 Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Mon, 31 Oct 2011 12:02:08 -0300 Subject: [media] it913x Support it9135 Verions 2 chip Support for version 2 type chips and other LNA versions of version 1 Scripts may be compressed slightly at a later stage. TODO Firmware loader However, things are a little confusing, it is not clear that dvb-usb-it9137-01.fw does not work with version 2 chips as in recent files both firmwares are the same. Should be applied to: 8133 Support for single ITE 9135 device. Signed-off-by: Malcolm Priestley Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/dvb/dvb-usb/it913x.c b/drivers/media/dvb/dvb-usb/it913x.c index c462261..a541904 100644 --- a/drivers/media/dvb/dvb-usb/it913x.c +++ b/drivers/media/dvb/dvb-usb/it913x.c @@ -60,15 +60,6 @@ struct it913x_state { u8 id; }; -struct ite_config { - u8 chip_ver; - u16 chip_type; - u32 firmware; - u8 tuner_id_0; - u8 tuner_id_1; - u8 dual_mode; -}; - struct ite_config it913x_config; static int it913x_bulk_write(struct usb_device *dev, @@ -390,8 +381,8 @@ static int it913x_identify_state(struct usb_device *udev, if (ret != 0) ret = it913x_wr_reg(udev, DEV_0, GPIOH1_O, 0x0); + props->num_adapters = 2; } - props->num_adapters = 2; } else props->num_adapters = 1; @@ -474,12 +465,17 @@ static int it913x_download_firmware(struct usb_device *udev, /* Tuner function */ if (it913x_config.dual_mode) ret |= it913x_wr_reg(udev, DEV_0_DMOD , 0xec4c, 0xa0); - - ret |= it913x_wr_reg(udev, DEV_0, PADODPU, 0x0); - ret |= it913x_wr_reg(udev, DEV_0, AGC_O_D, 0x0); - if (it913x_config.dual_mode) { - ret |= it913x_wr_reg(udev, DEV_1, PADODPU, 0x0); - ret |= it913x_wr_reg(udev, DEV_1, AGC_O_D, 0x0); + else + ret |= it913x_wr_reg(udev, DEV_0_DMOD , 0xec4c, 0x68); + + if ((it913x_config.chip_ver == 1) && + (it913x_config.chip_type == 0x9135)) { + ret |= it913x_wr_reg(udev, DEV_0, PADODPU, 0x0); + ret |= it913x_wr_reg(udev, DEV_0, AGC_O_D, 0x0); + if (it913x_config.dual_mode) { + ret |= it913x_wr_reg(udev, DEV_1, PADODPU, 0x0); + ret |= it913x_wr_reg(udev, DEV_1, AGC_O_D, 0x0); + } } return (ret < 0) ? -ENODEV : 0; @@ -501,31 +497,13 @@ static int it913x_frontend_attach(struct dvb_usb_adapter *adap) { struct usb_device *udev = adap->dev->udev; int ret = 0; - u8 adf = it913x_read_reg(udev, IO_MUX_POWER_CLK); u8 adap_addr = I2C_BASE_ADDR + (adap->id << 5); u16 ep_size = adap->props.fe[0].stream.u.bulk.buffersize; - u8 tuner_id, tuner_type; - if (adap->id == 0) - tuner_id = it913x_config.tuner_id_0; - else - tuner_id = it913x_config.tuner_id_1; - - /* TODO we always use IT9137 possible references here*/ - /* Documentation suggests don't care */ - switch (tuner_id) { - case 0x51: - case 0x52: - case 0x60: - case 0x61: - case 0x62: - default: - case 0x38: - tuner_type = IT9137; - } + it913x_config.adf = it913x_read_reg(udev, IO_MUX_POWER_CLK); adap->fe_adap[0].fe = dvb_attach(it913x_fe_attach, - &adap->dev->i2c_adap, adap_addr, adf, tuner_type); + &adap->dev->i2c_adap, adap_addr, &it913x_config); if (adap->id == 0 && adap->fe_adap[0].fe) { ret = it913x_wr_reg(udev, DEV_0_DMOD, MP2_SW_RST, 0x1); @@ -698,5 +676,5 @@ module_exit(it913x_module_exit); MODULE_AUTHOR("Malcolm Priestley "); MODULE_DESCRIPTION("it913x USB 2 Driver"); -MODULE_VERSION("1.07"); +MODULE_VERSION("1.08"); MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/frontends/it913x-fe-priv.h b/drivers/media/dvb/frontends/it913x-fe-priv.h index 1c6fb4b..abf1395 100644 --- a/drivers/media/dvb/frontends/it913x-fe-priv.h +++ b/drivers/media/dvb/frontends/it913x-fe-priv.h @@ -205,6 +205,10 @@ fe_modulation_t fe_con[] = { /* Standard demodulator functions */ static struct it913xset set_solo_fe[] = { + {PRO_LINK, GPIOH5_EN, {0x01}, 0x01}, + {PRO_LINK, GPIOH5_ON, {0x01}, 0x01}, + {PRO_LINK, GPIOH5_O, {0x00}, 0x01}, + {PRO_LINK, GPIOH5_O, {0x01}, 0x01}, {PRO_LINK, DVBT_INTEN, {0x04}, 0x01}, {PRO_LINK, DVBT_ENABLE, {0x05}, 0x01}, {PRO_DMOD, MP2IF_MPEG_PAR_MODE, {0x00}, 0x01}, @@ -233,8 +237,121 @@ static struct it913xset init_1[] = { {0xff, 0x0000, {0x00}, 0x00} /* Terminating Entry */ }; -/* ---------IT9137 0x38 tuner init---------- */ -static struct it913xset it9137_set[] = { + +/* Version 1 types */ +static struct it913xset it9135_v1[] = { + {PRO_DMOD, 0x0051, {0x01}, 0x01}, + {PRO_DMOD, 0x0070, {0x0a}, 0x01}, + {PRO_DMOD, 0x007e, {0x04}, 0x01}, + {PRO_DMOD, 0x0081, {0x0a}, 0x01}, + {PRO_DMOD, 0x008a, {0x01}, 0x01}, + {PRO_DMOD, 0x008e, {0x01}, 0x01}, + {PRO_DMOD, 0x0092, {0x06}, 0x01}, + {PRO_DMOD, 0x0099, {0x01}, 0x01}, + {PRO_DMOD, 0x009f, {0xe1}, 0x01}, + {PRO_DMOD, 0x00a0, {0xcf}, 0x01}, + {PRO_DMOD, 0x00a3, {0x01}, 0x01}, + {PRO_DMOD, 0x00a5, {0x01}, 0x01}, + {PRO_DMOD, 0x00a6, {0x01}, 0x01}, + {PRO_DMOD, 0x00a9, {0x00}, 0x01}, + {PRO_DMOD, 0x00aa, {0x01}, 0x01}, + {PRO_DMOD, 0x00b0, {0x01}, 0x01}, + {PRO_DMOD, 0x00c2, {0x05}, 0x01}, + {PRO_DMOD, 0x00c6, {0x19}, 0x01}, + {PRO_DMOD, 0xf000, {0x0f}, 0x01}, + {PRO_DMOD, 0xf016, {0x10}, 0x01}, + {PRO_DMOD, 0xf017, {0x04}, 0x01}, + {PRO_DMOD, 0xf018, {0x05}, 0x01}, + {PRO_DMOD, 0xf019, {0x04}, 0x01}, + {PRO_DMOD, 0xf01a, {0x05}, 0x01}, + {PRO_DMOD, 0xf021, {0x03}, 0x01}, + {PRO_DMOD, 0xf022, {0x0a}, 0x01}, + {PRO_DMOD, 0xf023, {0x0a}, 0x01}, + {PRO_DMOD, 0xf02b, {0x00}, 0x01}, + {PRO_DMOD, 0xf02c, {0x01}, 0x01}, + {PRO_DMOD, 0xf064, {0x03}, 0x01}, + {PRO_DMOD, 0xf065, {0xf9}, 0x01}, + {PRO_DMOD, 0xf066, {0x03}, 0x01}, + {PRO_DMOD, 0xf067, {0x01}, 0x01}, + {PRO_DMOD, 0xf06f, {0xe0}, 0x01}, + {PRO_DMOD, 0xf070, {0x03}, 0x01}, + {PRO_DMOD, 0xf072, {0x0f}, 0x01}, + {PRO_DMOD, 0xf073, {0x03}, 0x01}, + {PRO_DMOD, 0xf078, {0x00}, 0x01}, + {PRO_DMOD, 0xf087, {0x00}, 0x01}, + {PRO_DMOD, 0xf09b, {0x3f}, 0x01}, + {PRO_DMOD, 0xf09c, {0x00}, 0x01}, + {PRO_DMOD, 0xf09d, {0x20}, 0x01}, + {PRO_DMOD, 0xf09e, {0x00}, 0x01}, + {PRO_DMOD, 0xf09f, {0x0c}, 0x01}, + {PRO_DMOD, 0xf0a0, {0x00}, 0x01}, + {PRO_DMOD, 0xf130, {0x04}, 0x01}, + {PRO_DMOD, 0xf132, {0x04}, 0x01}, + {PRO_DMOD, 0xf144, {0x1a}, 0x01}, + {PRO_DMOD, 0xf146, {0x00}, 0x01}, + {PRO_DMOD, 0xf14a, {0x01}, 0x01}, + {PRO_DMOD, 0xf14c, {0x00}, 0x01}, + {PRO_DMOD, 0xf14d, {0x00}, 0x01}, + {PRO_DMOD, 0xf14f, {0x04}, 0x01}, + {PRO_DMOD, 0xf158, {0x7f}, 0x01}, + {PRO_DMOD, 0xf15a, {0x00}, 0x01}, + {PRO_DMOD, 0xf15b, {0x08}, 0x01}, + {PRO_DMOD, 0xf15d, {0x03}, 0x01}, + {PRO_DMOD, 0xf15e, {0x05}, 0x01}, + {PRO_DMOD, 0xf163, {0x05}, 0x01}, + {PRO_DMOD, 0xf166, {0x01}, 0x01}, + {PRO_DMOD, 0xf167, {0x40}, 0x01}, + {PRO_DMOD, 0xf168, {0x0f}, 0x01}, + {PRO_DMOD, 0xf17a, {0x00}, 0x01}, + {PRO_DMOD, 0xf17b, {0x00}, 0x01}, + {PRO_DMOD, 0xf183, {0x01}, 0x01}, + {PRO_DMOD, 0xf19d, {0x40}, 0x01}, + {PRO_DMOD, 0xf1bc, {0x36}, 0x01}, + {PRO_DMOD, 0xf1bd, {0x00}, 0x01}, + {PRO_DMOD, 0xf1cb, {0xa0}, 0x01}, + {PRO_DMOD, 0xf1cc, {0x01}, 0x01}, + {PRO_DMOD, 0xf204, {0x10}, 0x01}, + {PRO_DMOD, 0xf214, {0x00}, 0x01}, + {PRO_DMOD, 0xf40e, {0x0a}, 0x01}, + {PRO_DMOD, 0xf40f, {0x40}, 0x01}, + {PRO_DMOD, 0xf410, {0x08}, 0x01}, + {PRO_DMOD, 0xf55f, {0x0a}, 0x01}, + {PRO_DMOD, 0xf561, {0x15}, 0x01}, + {PRO_DMOD, 0xf562, {0x20}, 0x01}, + {PRO_DMOD, 0xf5df, {0xfb}, 0x01}, + {PRO_DMOD, 0xf5e0, {0x00}, 0x01}, + {PRO_DMOD, 0xf5e3, {0x09}, 0x01}, + {PRO_DMOD, 0xf5e4, {0x01}, 0x01}, + {PRO_DMOD, 0xf5e5, {0x01}, 0x01}, + {PRO_DMOD, 0xf5f8, {0x01}, 0x01}, + {PRO_DMOD, 0xf5fd, {0x01}, 0x01}, + {PRO_DMOD, 0xf600, {0x05}, 0x01}, + {PRO_DMOD, 0xf601, {0x08}, 0x01}, + {PRO_DMOD, 0xf602, {0x0b}, 0x01}, + {PRO_DMOD, 0xf603, {0x0e}, 0x01}, + {PRO_DMOD, 0xf604, {0x11}, 0x01}, + {PRO_DMOD, 0xf605, {0x14}, 0x01}, + {PRO_DMOD, 0xf606, {0x17}, 0x01}, + {PRO_DMOD, 0xf607, {0x1f}, 0x01}, + {PRO_DMOD, 0xf60e, {0x00}, 0x01}, + {PRO_DMOD, 0xf60f, {0x04}, 0x01}, + {PRO_DMOD, 0xf610, {0x32}, 0x01}, + {PRO_DMOD, 0xf611, {0x10}, 0x01}, + {PRO_DMOD, 0xf707, {0xfc}, 0x01}, + {PRO_DMOD, 0xf708, {0x00}, 0x01}, + {PRO_DMOD, 0xf709, {0x37}, 0x01}, + {PRO_DMOD, 0xf70a, {0x00}, 0x01}, + {PRO_DMOD, 0xf78b, {0x01}, 0x01}, + {PRO_DMOD, 0xf80f, {0x40}, 0x01}, + {PRO_DMOD, 0xf810, {0x54}, 0x01}, + {PRO_DMOD, 0xf811, {0x5a}, 0x01}, + {PRO_DMOD, 0xf905, {0x01}, 0x01}, + {PRO_DMOD, 0xfb06, {0x03}, 0x01}, + {PRO_DMOD, 0xfd8b, {0x00}, 0x01}, + {0xff, 0x0000, {0x00}, 0x00} /* Terminating Entry */ +}; + +static struct it913xset it9135_38[] = { {PRO_DMOD, 0x0043, {0x00}, 0x01}, {PRO_DMOD, 0x0046, {0x38}, 0x01}, {PRO_DMOD, 0x0051, {0x01}, 0x01}, @@ -244,7 +361,7 @@ static struct it913xset it9137_set[] = { {PRO_DMOD, 0x0075, {0x8c, 0x8c, 0x8c, 0xc8, 0x01}, 0x05}, {PRO_DMOD, 0x007e, {0x04, 0x00}, 0x02}, {PRO_DMOD, 0x0081, { 0x0a, 0x12, 0x02, 0x0a, 0x03, 0xc8, 0xb8, - 0xd0, 0xc3, 0x01 }, 0x0a}, + 0xd0, 0xc3, 0x01}, 0x0a}, {PRO_DMOD, 0x008e, {0x01}, 0x01}, {PRO_DMOD, 0x0092, {0x06, 0x00, 0x00, 0x00, 0x00}, 0x05}, {PRO_DMOD, 0x0099, {0x01}, 0x01}, @@ -262,15 +379,25 @@ static struct it913xset it9137_set[] = { {PRO_DMOD, 0x00f3, {0x05, 0x8c, 0x8c}, 0x03}, {PRO_DMOD, 0x00f8, {0x03, 0x06, 0x06}, 0x03}, {PRO_DMOD, 0x00fc, { 0x02, 0x02, 0x02, 0x09, 0x50, 0x7b, 0x77, - 0x00, 0x02, 0xc8, 0x05, 0x7b }, 0x0c}, + 0x00, 0x02, 0xc8, 0x05, 0x7b}, 0x0c}, {PRO_DMOD, 0x0109, {0x02}, 0x01}, - {PRO_DMOD, 0x0115, {0x0a, 0x03}, 0x02}, - {PRO_DMOD, 0x011a, {0xc8, 0x7b, 0xbc, 0xa0}, 0x04}, + {PRO_DMOD, 0x0115, {0x0a, 0x03, 0x02, 0x80}, 0x04}, + {PRO_DMOD, 0x011a, {0xc8, 0x7b, 0x8a, 0xa0}, 0x04}, {PRO_DMOD, 0x0122, {0x02, 0x18, 0xc3}, 0x03}, {PRO_DMOD, 0x0127, {0x00, 0x07}, 0x02}, {PRO_DMOD, 0x012a, {0x53, 0x51, 0x4e, 0x43}, 0x04}, {PRO_DMOD, 0x0137, {0x01, 0x00, 0x07, 0x00, 0x06}, 0x05}, - {PRO_DMOD, 0x013d, {0x00, 0x01, 0x5b, 0xc8}, 0x04}, + {PRO_DMOD, 0x013d, {0x00, 0x01, 0x5b, 0xc8, 0x59}, 0x05}, + {PRO_DMOD, 0xf000, {0x0f}, 0x01}, + {PRO_DMOD, 0xf016, {0x10, 0x04, 0x05, 0x04, 0x05}, 0x05}, + {PRO_DMOD, 0xf01f, {0x8c, 0x00, 0x03, 0x0a, 0x0a}, 0x05}, + {PRO_DMOD, 0xf029, {0x8c, 0x00, 0x00, 0x01}, 0x04}, + {PRO_DMOD, 0xf064, {0x03, 0xf9, 0x03, 0x01}, 0x04}, + {PRO_DMOD, 0xf06f, {0xe0, 0x03}, 0x02}, + {PRO_DMOD, 0xf072, {0x0f, 0x03}, 0x02}, + {PRO_DMOD, 0xf077, {0x01, 0x00}, 0x02}, + {PRO_DMOD, 0xf085, {0x00, 0x02, 0x00}, 0x03}, + {PRO_DMOD, 0xf09b, {0x3f, 0x00, 0x20, 0x00, 0x0c, 0x00}, 0x06}, {PRO_DMOD, 0xf130, {0x04}, 0x01}, {PRO_DMOD, 0xf132, {0x04}, 0x01}, {PRO_DMOD, 0xf144, {0x1a}, 0x01}, @@ -301,7 +428,7 @@ static struct it913xset it9137_set[] = { {PRO_DMOD, 0xf5f8, {0x01}, 0x01}, {PRO_DMOD, 0xf5fd, {0x01}, 0x01}, {PRO_DMOD, 0xf600, { 0x05, 0x08, 0x0b, 0x0e, 0x11, 0x14, 0x17, - 0x1f }, 0x08}, + 0x1f}, 0x08}, {PRO_DMOD, 0xf60e, {0x00, 0x04, 0x32, 0x10}, 0x04}, {PRO_DMOD, 0xf707, {0xfc, 0x00, 0x37, 0x00}, 0x04}, {PRO_DMOD, 0xf78b, {0x01}, 0x01}, @@ -309,13 +436,578 @@ static struct it913xset it9137_set[] = { {PRO_DMOD, 0xf905, {0x01}, 0x01}, {PRO_DMOD, 0xfb06, {0x03}, 0x01}, {PRO_DMOD, 0xfd8b, {0x00}, 0x01}, - {PRO_LINK, GPIOH5_EN, {0x01}, 0x01}, - {PRO_LINK, GPIOH5_ON, {0x01}, 0x01}, - {PRO_LINK, GPIOH5_O, {0x00}, 0x01}, - {PRO_LINK, GPIOH5_O, {0x01}, 0x01}, - {0xff, 0x0000, {0x00}, 0x00}, /* Terminating Entry */ + {0xff, 0x0000, {0x00}, 0x00} /* Terminating Entry */ +}; + +static struct it913xset it9135_51[] = { + {PRO_DMOD, 0x0043, {0x00}, 0x01}, + {PRO_DMOD, 0x0046, {0x51}, 0x01}, + {PRO_DMOD, 0x0051, {0x01}, 0x01}, + {PRO_DMOD, 0x005f, {0x00, 0x00}, 0x02}, + {PRO_DMOD, 0x0068, {0x0a}, 0x01}, + {PRO_DMOD, 0x0070, {0x0a, 0x06, 0x02}, 0x03}, + {PRO_DMOD, 0x0075, {0x8c, 0x8c, 0x8c, 0xc8, 0x01}, 0x05}, + {PRO_DMOD, 0x007e, {0x04, 0x00}, 0x02}, + {PRO_DMOD, 0x0081, { 0x0a, 0x12, 0x02, 0x0a, 0x03, 0xc0, 0x96, + 0xcf, 0xc3, 0x01}, 0x0a}, + {PRO_DMOD, 0x008e, {0x01}, 0x01}, + {PRO_DMOD, 0x0092, {0x06, 0x00, 0x00, 0x00, 0x00}, 0x05}, + {PRO_DMOD, 0x0099, {0x01}, 0x01}, + {PRO_DMOD, 0x009b, {0x3c, 0x28}, 0x02}, + {PRO_DMOD, 0x009f, {0xe1, 0xcf}, 0x02}, + {PRO_DMOD, 0x00a3, {0x01, 0x5a, 0x01, 0x01}, 0x04}, + {PRO_DMOD, 0x00a9, {0x00, 0x01}, 0x02}, + {PRO_DMOD, 0x00b0, {0x01}, 0x01}, + {PRO_DMOD, 0x00b3, {0x02, 0x3c}, 0x02}, + {PRO_DMOD, 0x00b6, {0x14}, 0x01}, + {PRO_DMOD, 0x00c0, {0x11, 0x00, 0x05}, 0x03}, + {PRO_DMOD, 0x00c4, {0x00}, 0x01}, + {PRO_DMOD, 0x00c6, {0x19, 0x00}, 0x02}, + {PRO_DMOD, 0x00cc, {0x2e, 0x51, 0x33}, 0x03}, + {PRO_DMOD, 0x00f3, {0x05, 0x8c, 0x8c}, 0x03}, + {PRO_DMOD, 0x00f8, {0x03, 0x06, 0x06}, 0x03}, + {PRO_DMOD, 0x00fc, { 0x03, 0x02, 0x02, 0x09, 0x50, 0x7a, 0x77, + 0x01, 0x02, 0xb0, 0x02, 0x7a}, 0x0c}, + {PRO_DMOD, 0x0109, {0x02}, 0x01}, + {PRO_DMOD, 0x0115, {0x0a, 0x03, 0x02, 0x80}, 0x04}, + {PRO_DMOD, 0x011a, {0xc0, 0x7a, 0xac, 0x8c}, 0x04}, + {PRO_DMOD, 0x0122, {0x02, 0x70, 0xa4}, 0x03}, + {PRO_DMOD, 0x0127, {0x00, 0x07}, 0x02}, + {PRO_DMOD, 0x012a, {0x53, 0x51, 0x4e, 0x43}, 0x04}, + {PRO_DMOD, 0x0137, {0x01, 0x00, 0x07, 0x00, 0x06}, 0x05}, + {PRO_DMOD, 0x013d, {0x00, 0x01, 0x5b, 0xc0, 0x59}, 0x05}, + {PRO_DMOD, 0xf000, {0x0f}, 0x01}, + {PRO_DMOD, 0xf016, {0x10, 0x04, 0x05, 0x04, 0x05}, 0x05}, + {PRO_DMOD, 0xf01f, {0x8c, 0x00, 0x03, 0x0a, 0x0a}, 0x05}, + {PRO_DMOD, 0xf029, {0x8c, 0x00, 0x00, 0x01}, 0x04}, + {PRO_DMOD, 0xf064, {0x03, 0xf9, 0x03, 0x01}, 0x04}, + {PRO_DMOD, 0xf06f, {0xe0, 0x03}, 0x02}, + {PRO_DMOD, 0xf072, {0x0f, 0x03}, 0x02}, + {PRO_DMOD, 0xf077, {0x01, 0x00}, 0x02}, + {PRO_DMOD, 0xf085, {0xc0, 0x01, 0x00}, 0x03}, + {PRO_DMOD, 0xf09b, {0x3f, 0x00, 0x20, 0x00, 0x0c, 0x00}, 0x06}, + {PRO_DMOD, 0xf130, {0x04}, 0x01}, + {PRO_DMOD, 0xf132, {0x04}, 0x01}, + {PRO_DMOD, 0xf144, {0x1a}, 0x01}, + {PRO_DMOD, 0xf146, {0x00}, 0x01}, + {PRO_DMOD, 0xf14a, {0x01}, 0x01}, + {PRO_DMOD, 0xf14c, {0x00, 0x00}, 0x02}, + {PRO_DMOD, 0xf14f, {0x04}, 0x01}, + {PRO_DMOD, 0xf158, {0x7f}, 0x01}, + {PRO_DMOD, 0xf15a, {0x00, 0x08}, 0x02}, + {PRO_DMOD, 0xf15d, {0x03, 0x05}, 0x02}, + {PRO_DMOD, 0xf163, {0x05}, 0x01}, + {PRO_DMOD, 0xf166, {0x01, 0x40, 0x0f}, 0x03}, + {PRO_DMOD, 0xf17a, {0x00, 0x00}, 0x02}, + {PRO_DMOD, 0xf183, {0x01}, 0x01}, + {PRO_DMOD, 0xf19d, {0x40}, 0x01}, + {PRO_DMOD, 0xf1bc, {0x36, 0x00}, 0x02}, + {PRO_DMOD, 0xf1cb, {0xa0, 0x01}, 0x02}, + {PRO_DMOD, 0xf204, {0x10}, 0x01}, + {PRO_DMOD, 0xf214, {0x00}, 0x01}, + {PRO_DMOD, 0xf24c, {0x88, 0x95, 0x9a, 0x90}, 0x04}, + {PRO_DMOD, 0xf25a, {0x07, 0xe8, 0x03, 0xb0, 0x04}, 0x05}, + {PRO_DMOD, 0xf270, {0x01, 0x02, 0x01, 0x02}, 0x04}, + {PRO_DMOD, 0xf40e, {0x0a, 0x40, 0x08}, 0x03}, + {PRO_DMOD, 0xf55f, {0x0a}, 0x01}, + {PRO_DMOD, 0xf561, {0x15, 0x20}, 0x02}, + {PRO_DMOD, 0xf5df, {0xfb, 0x00}, 0x02}, + {PRO_DMOD, 0xf5e3, {0x09, 0x01, 0x01}, 0x03}, + {PRO_DMOD, 0xf5f8, {0x01}, 0x01}, + {PRO_DMOD, 0xf5fd, {0x01}, 0x01}, + {PRO_DMOD, 0xf600, { 0x05, 0x08, 0x0b, 0x0e, 0x11, 0x14, 0x17, + 0x1f}, 0x08}, + {PRO_DMOD, 0xf60e, {0x00, 0x04, 0x32, 0x10}, 0x04}, + {PRO_DMOD, 0xf707, {0xfc, 0x00, 0x37, 0x00}, 0x04}, + {PRO_DMOD, 0xf78b, {0x01}, 0x01}, + {PRO_DMOD, 0xf80f, {0x40, 0x54, 0x5a}, 0x03}, + {PRO_DMOD, 0xf905, {0x01}, 0x01}, + {PRO_DMOD, 0xfb06, {0x03}, 0x01}, + {PRO_DMOD, 0xfd8b, {0x00}, 0x01}, + {0xff, 0x0000, {0x00}, 0x00} /* Terminating Entry */ +}; + +static struct it913xset it9135_52[] = { + {PRO_DMOD, 0x0043, {0x00}, 0x01}, + {PRO_DMOD, 0x0046, {0x52}, 0x01}, + {PRO_DMOD, 0x0051, {0x01}, 0x01}, + {PRO_DMOD, 0x005f, {0x00, 0x00}, 0x02}, + {PRO_DMOD, 0x0068, {0x10}, 0x01}, + {PRO_DMOD, 0x0070, {0x0a, 0x05, 0x02}, 0x03}, + {PRO_DMOD, 0x0075, {0x8c, 0x8c, 0x8c, 0xa0, 0x01}, 0x05}, + {PRO_DMOD, 0x007e, {0x04, 0x00}, 0x02}, + {PRO_DMOD, 0x0081, { 0x0a, 0x12, 0x03, 0x0a, 0x03, 0xb3, 0x97, + 0xc0, 0x9e, 0x01}, 0x0a}, + {PRO_DMOD, 0x008e, {0x01}, 0x01}, + {PRO_DMOD, 0x0092, {0x06, 0x00, 0x00, 0x00, 0x00}, 0x05}, + {PRO_DMOD, 0x0099, {0x01}, 0x01}, + {PRO_DMOD, 0x009b, {0x3c, 0x28}, 0x02}, + {PRO_DMOD, 0x009f, {0xe1, 0xcf}, 0x02}, + {PRO_DMOD, 0x00a3, {0x01, 0x5c, 0x01, 0x01}, 0x04}, + {PRO_DMOD, 0x00a9, {0x00, 0x01}, 0x02}, + {PRO_DMOD, 0x00b0, {0x01}, 0x01}, + {PRO_DMOD, 0x00b3, {0x02, 0x3c}, 0x02}, + {PRO_DMOD, 0x00b6, {0x14}, 0x01}, + {PRO_DMOD, 0x00c0, {0x11, 0x00, 0x05}, 0x03}, + {PRO_DMOD, 0x00c4, {0x00}, 0x01}, + {PRO_DMOD, 0x00c6, {0x19, 0x00}, 0x02}, + {PRO_DMOD, 0x00cc, {0x2e, 0x51, 0x33}, 0x03}, + {PRO_DMOD, 0x00f3, {0x05, 0x91, 0x8c}, 0x03}, + {PRO_DMOD, 0x00f8, {0x03, 0x06, 0x06}, 0x03}, + {PRO_DMOD, 0x00fc, { 0x03, 0x02, 0x02, 0x09, 0x50, 0x74, 0x77, + 0x02, 0x02, 0xae, 0x02, 0x6e}, 0x0c}, + {PRO_DMOD, 0x0109, {0x02}, 0x01}, + {PRO_DMOD, 0x0115, {0x0a, 0x03, 0x02, 0x80}, 0x04}, + {PRO_DMOD, 0x011a, {0xcd, 0x62, 0xa4, 0x8c}, 0x04}, + {PRO_DMOD, 0x0122, {0x03, 0x18, 0x9e}, 0x03}, + {PRO_DMOD, 0x0127, {0x00, 0x07}, 0x02}, + {PRO_DMOD, 0x012a, {0x53, 0x51, 0x4e, 0x43}, 0x04}, + {PRO_DMOD, 0x0137, {0x00, 0x00, 0x07, 0x00, 0x06}, 0x05}, + {PRO_DMOD, 0x013d, {0x00, 0x01, 0x5b, 0xb6, 0x59}, 0x05}, + {PRO_DMOD, 0xf000, {0x0f}, 0x01}, + {PRO_DMOD, 0xf016, {0x10, 0x04, 0x05, 0x04, 0x05}, 0x05}, + {PRO_DMOD, 0xf01f, {0x8c, 0x00, 0x03, 0x0a, 0x0a}, 0x05}, + {PRO_DMOD, 0xf029, {0x8c, 0x00, 0x00, 0x01}, 0x04}, + {PRO_DMOD, 0xf064, {0x03, 0xf9, 0x03, 0x01}, 0x04}, + {PRO_DMOD, 0xf06f, {0xe0, 0x03}, 0x02}, + {PRO_DMOD, 0xf072, {0x0f, 0x03}, 0x02}, + {PRO_DMOD, 0xf077, {0x01, 0x00}, 0x02}, + {PRO_DMOD, 0xf085, {0xc0, 0x01, 0x00}, 0x03}, + {PRO_DMOD, 0xf09b, {0x3f, 0x00, 0x20, 0x00, 0x0c, 0x00}, 0x06}, + {PRO_DMOD, 0xf130, {0x04}, 0x01}, + {PRO_DMOD, 0xf132, {0x04}, 0x01}, + {PRO_DMOD, 0xf144, {0x1a}, 0x01}, + {PRO_DMOD, 0xf146, {0x00}, 0x01}, + {PRO_DMOD, 0xf14a, {0x01}, 0x01}, + {PRO_DMOD, 0xf14c, {0x00, 0x00}, 0x02}, + {PRO_DMOD, 0xf14f, {0x04}, 0x01}, + {PRO_DMOD, 0xf158, {0x7f}, 0x01}, + {PRO_DMOD, 0xf15a, {0x00, 0x08}, 0x02}, + {PRO_DMOD, 0xf15d, {0x03, 0x05}, 0x02}, + {PRO_DMOD, 0xf163, {0x05}, 0x01}, + {PRO_DMOD, 0xf166, {0x01, 0x40, 0x0f}, 0x03}, + {PRO_DMOD, 0xf17a, {0x00, 0x00}, 0x02}, + {PRO_DMOD, 0xf183, {0x01}, 0x01}, + {PRO_DMOD, 0xf19d, {0x40}, 0x01}, + {PRO_DMOD, 0xf1bc, {0x36, 0x00}, 0x02}, + {PRO_DMOD, 0xf1cb, {0xa0, 0x01}, 0x02}, + {PRO_DMOD, 0xf204, {0x10}, 0x01}, + {PRO_DMOD, 0xf214, {0x00}, 0x01}, + {PRO_DMOD, 0xf24c, {0x88, 0x95, 0x9a, 0x90}, 0x04}, + {PRO_DMOD, 0xf25a, {0x07, 0xe8, 0x03, 0xb0, 0x04}, 0x05}, + {PRO_DMOD, 0xf270, {0x01, 0x02, 0x01, 0x02}, 0x04}, + {PRO_DMOD, 0xf40e, {0x0a, 0x40, 0x08}, 0x03}, + {PRO_DMOD, 0xf55f, {0x0a}, 0x01}, + {PRO_DMOD, 0xf561, {0x15, 0x20}, 0x02}, + {PRO_DMOD, 0xf5df, {0xfb, 0x00}, 0x02}, + {PRO_DMOD, 0xf5e3, {0x09, 0x01, 0x01}, 0x03}, + {PRO_DMOD, 0xf5f8, {0x01}, 0x01}, + {PRO_DMOD, 0xf5fd, {0x01}, 0x01}, + {PRO_DMOD, 0xf600, {0x05, 0x08, 0x0b, 0x0e, 0x11, 0x14, 0x17, + 0x1f}, 0x08}, + {PRO_DMOD, 0xf60e, {0x00, 0x04, 0x32, 0x10}, 0x04}, + {PRO_DMOD, 0xf707, {0xfc, 0x00, 0x37, 0x00}, 0x04}, + {PRO_DMOD, 0xf78b, {0x01}, 0x01}, + {PRO_DMOD, 0xf80f, {0x40, 0x54, 0x5a}, 0x03}, + {PRO_DMOD, 0xf905, {0x01}, 0x01}, + {PRO_DMOD, 0xfb06, {0x03}, 0x01}, + {PRO_DMOD, 0xfd8b, {0x00}, 0x01}, + {0xff, 0x0000, {0x00}, 0x00} /* Terminating Entry */ +}; + +/* Version 2 types */ +static struct it913xset it9135_v2[] = { + {PRO_DMOD, 0x0051, {0x01}, 0x01}, + {PRO_DMOD, 0x0070, {0x0a}, 0x01}, + {PRO_DMOD, 0x007e, {0x04}, 0x01}, + {PRO_DMOD, 0x0081, {0x0a}, 0x01}, + {PRO_DMOD, 0x008a, {0x01}, 0x01}, + {PRO_DMOD, 0x008e, {0x01}, 0x01}, + {PRO_DMOD, 0x0092, {0x06}, 0x01}, + {PRO_DMOD, 0x0099, {0x01}, 0x01}, + {PRO_DMOD, 0x009f, {0xe1}, 0x01}, + {PRO_DMOD, 0x00a0, {0xcf}, 0x01}, + {PRO_DMOD, 0x00a3, {0x01}, 0x01}, + {PRO_DMOD, 0x00a5, {0x01}, 0x01}, + {PRO_DMOD, 0x00a6, {0x01}, 0x01}, + {PRO_DMOD, 0x00a9, {0x00}, 0x01}, + {PRO_DMOD, 0x00aa, {0x01}, 0x01}, + {PRO_DMOD, 0x00b0, {0x01}, 0x01}, + {PRO_DMOD, 0x00c2, {0x05}, 0x01}, + {PRO_DMOD, 0x00c6, {0x19}, 0x01}, + {PRO_DMOD, 0xf000, {0x0f}, 0x01}, + {PRO_DMOD, 0xf02b, {0x00}, 0x01}, + {PRO_DMOD, 0xf064, {0x03}, 0x01}, + {PRO_DMOD, 0xf065, {0xf9}, 0x01}, + {PRO_DMOD, 0xf066, {0x03}, 0x01}, + {PRO_DMOD, 0xf067, {0x01}, 0x01}, + {PRO_DMOD, 0xf06f, {0xe0}, 0x01}, + {PRO_DMOD, 0xf070, {0x03}, 0x01}, + {PRO_DMOD, 0xf072, {0x0f}, 0x01}, + {PRO_DMOD, 0xf073, {0x03}, 0x01}, + {PRO_DMOD, 0xf078, {0x00}, 0x01}, + {PRO_DMOD, 0xf087, {0x00}, 0x01}, + {PRO_DMOD, 0xf09b, {0x3f}, 0x01}, + {PRO_DMOD, 0xf09c, {0x00}, 0x01}, + {PRO_DMOD, 0xf09d, {0x20}, 0x01}, + {PRO_DMOD, 0xf09e, {0x00}, 0x01}, + {PRO_DMOD, 0xf09f, {0x0c}, 0x01}, + {PRO_DMOD, 0xf0a0, {0x00}, 0x01}, + {PRO_DMOD, 0xf130, {0x04}, 0x01}, + {PRO_DMOD, 0xf132, {0x04}, 0x01}, + {PRO_DMOD, 0xf144, {0x1a}, 0x01}, + {PRO_DMOD, 0xf146, {0x00}, 0x01}, + {PRO_DMOD, 0xf14a, {0x01}, 0x01}, + {PRO_DMOD, 0xf14c, {0x00}, 0x01}, + {PRO_DMOD, 0xf14d, {0x00}, 0x01}, + {PRO_DMOD, 0xf14f, {0x04}, 0x01}, + {PRO_DMOD, 0xf158, {0x7f}, 0x01}, + {PRO_DMOD, 0xf15a, {0x00}, 0x01}, + {PRO_DMOD, 0xf15b, {0x08}, 0x01}, + {PRO_DMOD, 0xf15d, {0x03}, 0x01}, + {PRO_DMOD, 0xf15e, {0x05}, 0x01}, + {PRO_DMOD, 0xf163, {0x05}, 0x01}, + {PRO_DMOD, 0xf166, {0x01}, 0x01}, + {PRO_DMOD, 0xf167, {0x40}, 0x01}, + {PRO_DMOD, 0xf168, {0x0f}, 0x01}, + {PRO_DMOD, 0xf17a, {0x00}, 0x01}, + {PRO_DMOD, 0xf17b, {0x00}, 0x01}, + {PRO_DMOD, 0xf183, {0x01}, 0x01}, + {PRO_DMOD, 0xf19d, {0x40}, 0x01}, + {PRO_DMOD, 0xf1bc, {0x36}, 0x01}, + {PRO_DMOD, 0xf1bd, {0x00}, 0x01}, + {PRO_DMOD, 0xf1cb, {0xa0}, 0x01}, + {PRO_DMOD, 0xf1cc, {0x01}, 0x01}, + {PRO_DMOD, 0xf204, {0x10}, 0x01}, + {PRO_DMOD, 0xf214, {0x00}, 0x01}, + {PRO_DMOD, 0xf40e, {0x0a}, 0x01}, + {PRO_DMOD, 0xf40f, {0x40}, 0x01}, + {PRO_DMOD, 0xf410, {0x08}, 0x01}, + {PRO_DMOD, 0xf55f, {0x0a}, 0x01}, + {PRO_DMOD, 0xf561, {0x15}, 0x01}, + {PRO_DMOD, 0xf562, {0x20}, 0x01}, + {PRO_DMOD, 0xf5e3, {0x09}, 0x01}, + {PRO_DMOD, 0xf5e4, {0x01}, 0x01}, + {PRO_DMOD, 0xf5e5, {0x01}, 0x01}, + {PRO_DMOD, 0xf600, {0x05}, 0x01}, + {PRO_DMOD, 0xf601, {0x08}, 0x01}, + {PRO_DMOD, 0xf602, {0x0b}, 0x01}, + {PRO_DMOD, 0xf603, {0x0e}, 0x01}, + {PRO_DMOD, 0xf604, {0x11}, 0x01}, + {PRO_DMOD, 0xf605, {0x14}, 0x01}, + {PRO_DMOD, 0xf606, {0x17}, 0x01}, + {PRO_DMOD, 0xf607, {0x1f}, 0x01}, + {PRO_DMOD, 0xf60e, {0x00}, 0x01}, + {PRO_DMOD, 0xf60f, {0x04}, 0x01}, + {PRO_DMOD, 0xf610, {0x32}, 0x01}, + {PRO_DMOD, 0xf611, {0x10}, 0x01}, + {PRO_DMOD, 0xf707, {0xfc}, 0x01}, + {PRO_DMOD, 0xf708, {0x00}, 0x01}, + {PRO_DMOD, 0xf709, {0x37}, 0x01}, + {PRO_DMOD, 0xf70a, {0x00}, 0x01}, + {PRO_DMOD, 0xf78b, {0x01}, 0x01}, + {PRO_DMOD, 0xf80f, {0x40}, 0x01}, + {PRO_DMOD, 0xf810, {0x54}, 0x01}, + {PRO_DMOD, 0xf811, {0x5a}, 0x01}, + {PRO_DMOD, 0xf905, {0x01}, 0x01}, + {PRO_DMOD, 0xfb06, {0x03}, 0x01}, + {PRO_DMOD, 0xfd8b, {0x00}, 0x01}, + {0xff, 0x0000, {0x00}, 0x00} /* Terminating Entry */ +}; + +static struct it913xset it9135_60[] = { + {PRO_DMOD, 0x0043, {0x00}, 0x01}, + {PRO_DMOD, 0x0046, {0x60}, 0x01}, + {PRO_DMOD, 0x0051, {0x01}, 0x01}, + {PRO_DMOD, 0x005f, {0x00, 0x00}, 0x02}, + {PRO_DMOD, 0x0068, {0x0a}, 0x01}, + {PRO_DMOD, 0x006a, {0x03}, 0x01}, + {PRO_DMOD, 0x0070, {0x0a, 0x05, 0x02}, 0x03}, + {PRO_DMOD, 0x0075, {0x8c, 0x8c, 0x8c, 0x8c, 0x01}, 0x05}, + {PRO_DMOD, 0x007e, {0x04}, 0x01}, + {PRO_DMOD, 0x0081, {0x0a, 0x12}, 0x02}, + {PRO_DMOD, 0x0084, {0x0a, 0x33, 0xbe, 0xa0, 0xc6, 0xb6, 0x01}, 0x07}, + {PRO_DMOD, 0x008e, {0x01}, 0x01}, + {PRO_DMOD, 0x0092, {0x06, 0x00, 0x00, 0x00, 0x00}, 0x05}, + {PRO_DMOD, 0x0099, {0x01}, 0x01}, + {PRO_DMOD, 0x009b, {0x3c, 0x28}, 0x02}, + {PRO_DMOD, 0x009f, {0xe1, 0xcf}, 0x02}, + {PRO_DMOD, 0x00a3, {0x01, 0x5a, 0x01, 0x01}, 0x04}, + {PRO_DMOD, 0x00a9, {0x00, 0x01}, 0x02}, + {PRO_DMOD, 0x00b0, {0x01}, 0x01}, + {PRO_DMOD, 0x00b3, {0x02, 0x3a}, 0x02}, + {PRO_DMOD, 0x00b6, {0x14}, 0x01}, + {PRO_DMOD, 0x00c0, {0x11, 0x00, 0x05, 0x01, 0x00}, 0x05}, + {PRO_DMOD, 0x00c6, {0x19, 0x00}, 0x02}, + {PRO_DMOD, 0x00cb, {0x32, 0x2c, 0x4f, 0x30}, 0x04}, + {PRO_DMOD, 0x00f3, {0x05, 0xa0, 0x8c}, 0x03}, + {PRO_DMOD, 0x00f8, {0x03, 0x06, 0x06}, 0x03}, + {PRO_DMOD, 0x00fc, { 0x03, 0x03, 0x02, 0x0a, 0x50, 0x7b, 0x8c, + 0x00, 0x02, 0xbe, 0x00}, 0x0b}, + {PRO_DMOD, 0x0109, {0x02}, 0x01}, + {PRO_DMOD, 0x0115, {0x0a, 0x03}, 0x02}, + {PRO_DMOD, 0x011a, {0xbe}, 0x01}, + {PRO_DMOD, 0x0124, {0xae}, 0x01}, + {PRO_DMOD, 0x0127, {0x00}, 0x01}, + {PRO_DMOD, 0x012a, {0x56, 0x50, 0x47, 0x42}, 0x04}, + {PRO_DMOD, 0x0137, {0x00}, 0x01}, + {PRO_DMOD, 0x013b, {0x08}, 0x01}, + {PRO_DMOD, 0x013f, {0x5b}, 0x01}, + {PRO_DMOD, 0x0141, { 0x59, 0xf9, 0x19, 0x19, 0x8c, 0x8c, 0x8c, + 0x6e, 0x8c, 0x50, 0x8c, 0x8c, 0xac, 0xc6, + 0x33}, 0x0f}, + {PRO_DMOD, 0x0151, {0x28}, 0x01}, + {PRO_DMOD, 0x0153, {0xbc}, 0x01}, + {PRO_DMOD, 0x0178, {0x09}, 0x01}, + {PRO_DMOD, 0x0181, {0x94, 0x6e}, 0x02}, + {PRO_DMOD, 0x0185, {0x24}, 0x01}, + {PRO_DMOD, 0x0187, {0x00, 0x00, 0xbe, 0x02, 0x80}, 0x05}, + {PRO_DMOD, 0xed02, {0xff}, 0x01}, + {PRO_DMOD, 0xee42, {0xff}, 0x01}, + {PRO_DMOD, 0xee82, {0xff}, 0x01}, + {PRO_DMOD, 0xf000, {0x0f}, 0x01}, + {PRO_DMOD, 0xf01f, {0x8c, 0x00}, 0x02}, + {PRO_DMOD, 0xf029, {0x8c, 0x00, 0x00}, 0x03}, + {PRO_DMOD, 0xf064, {0x03, 0xf9, 0x03, 0x01}, 0x04}, + {PRO_DMOD, 0xf06f, {0xe0, 0x03}, 0x02}, + {PRO_DMOD, 0xf072, {0x0f, 0x03}, 0x02}, + {PRO_DMOD, 0xf077, {0x01, 0x00}, 0x02}, + {PRO_DMOD, 0xf087, {0x00}, 0x01}, + {PRO_DMOD, 0xf09b, {0x3f, 0x00, 0x20, 0x00, 0x0c, 0x00}, 0x06}, + {PRO_DMOD, 0xf130, {0x04}, 0x01}, + {PRO_DMOD, 0xf132, {0x04}, 0x01}, + {PRO_DMOD, 0xf144, {0x1a}, 0x01}, + {PRO_DMOD, 0xf146, {0x00}, 0x01}, + {PRO_DMOD, 0xf14a, {0x01}, 0x01}, + {PRO_DMOD, 0xf14c, {0x00, 0x00}, 0x02}, + {PRO_DMOD, 0xf14f, {0x04}, 0x01}, + {PRO_DMOD, 0xf158, {0x7f}, 0x01}, + {PRO_DMOD, 0xf15a, {0x00, 0x08}, 0x02}, + {PRO_DMOD, 0xf15d, {0x03, 0x05}, 0x02}, + {PRO_DMOD, 0xf163, {0x05}, 0x01}, + {PRO_DMOD, 0xf166, {0x01, 0x40, 0x0f}, 0x03}, + {PRO_DMOD, 0xf17a, {0x00, 0x00}, 0x02}, + {PRO_DMOD, 0xf183, {0x01}, 0x01}, + {PRO_DMOD, 0xf19d, {0x40}, 0x01}, + {PRO_DMOD, 0xf1bc, {0x36, 0x00}, 0x02}, + {PRO_DMOD, 0xf1cb, {0xa0, 0x01}, 0x02}, + {PRO_DMOD, 0xf204, {0x10}, 0x01}, + {PRO_DMOD, 0xf214, {0x00}, 0x01}, + {PRO_DMOD, 0xf24c, {0x88, 0x95, 0x9a, 0x90}, 0x04}, + {PRO_DMOD, 0xf25a, {0x07, 0xe8, 0x03, 0xb0, 0x04}, 0x05}, + {PRO_DMOD, 0xf270, {0x01, 0x02, 0x01, 0x02}, 0x04}, + {PRO_DMOD, 0xf40e, {0x0a, 0x40, 0x08}, 0x03}, + {PRO_DMOD, 0xf55f, {0x0a}, 0x01}, + {PRO_DMOD, 0xf561, {0x15, 0x20}, 0x02}, + {PRO_DMOD, 0xf5e3, {0x09, 0x01, 0x01}, 0x03}, + {PRO_DMOD, 0xf600, {0x05, 0x08, 0x0b, 0x0e, 0x11, 0x14, 0x17 + , 0x1f}, 0x08}, + {PRO_DMOD, 0xf60e, {0x00, 0x04, 0x32, 0x10}, 0x04}, + {PRO_DMOD, 0xf707, {0xfc, 0x00, 0x37, 0x00}, 0x04}, + {PRO_DMOD, 0xf78b, {0x01}, 0x01}, + {PRO_DMOD, 0xf80f, {0x40, 0x54, 0x5a}, 0x03}, + {PRO_DMOD, 0xf905, {0x01}, 0x01}, + {PRO_DMOD, 0xfb06, {0x03}, 0x01}, + {PRO_DMOD, 0xfd8b, {0x00}, 0x01}, + {0xff, 0x0000, {0x00}, 0x00} /* Terminating Entry */ +}; + +static struct it913xset it9135_61[] = { + {PRO_DMOD, 0x0043, {0x00}, 0x01}, + {PRO_DMOD, 0x0046, {0x61}, 0x01}, + {PRO_DMOD, 0x0051, {0x01}, 0x01}, + {PRO_DMOD, 0x005f, {0x00, 0x00}, 0x02}, + {PRO_DMOD, 0x0068, {0x06}, 0x01}, + {PRO_DMOD, 0x006a, {0x03}, 0x01}, + {PRO_DMOD, 0x0070, {0x0a, 0x05, 0x02}, 0x03}, + {PRO_DMOD, 0x0075, {0x8c, 0x8c, 0x8c, 0x90, 0x01}, 0x05}, + {PRO_DMOD, 0x007e, {0x04}, 0x01}, + {PRO_DMOD, 0x0081, {0x0a, 0x12}, 0x02}, + {PRO_DMOD, 0x0084, {0x0a, 0x33, 0xbc, 0x9c, 0xcc, 0xa8, 0x01}, 0x07}, + {PRO_DMOD, 0x008e, {0x01}, 0x01}, + {PRO_DMOD, 0x0092, {0x06, 0x00, 0x00, 0x00, 0x00}, 0x05}, + {PRO_DMOD, 0x0099, {0x01}, 0x01}, + {PRO_DMOD, 0x009b, {0x3c, 0x28}, 0x02}, + {PRO_DMOD, 0x009f, {0xe1, 0xcf}, 0x02}, + {PRO_DMOD, 0x00a3, {0x01, 0x5c, 0x01, 0x01}, 0x04}, + {PRO_DMOD, 0x00a9, {0x00, 0x01}, 0x02}, + {PRO_DMOD, 0x00b0, {0x01}, 0x01}, + {PRO_DMOD, 0x00b3, {0x02, 0x3a}, 0x02}, + {PRO_DMOD, 0x00b6, {0x14}, 0x01}, + {PRO_DMOD, 0x00c0, {0x11, 0x00, 0x05, 0x01, 0x00}, 0x05}, + {PRO_DMOD, 0x00c6, {0x19, 0x00}, 0x02}, + {PRO_DMOD, 0x00cb, {0x32, 0x2c, 0x4f, 0x30}, 0x04}, + {PRO_DMOD, 0x00f3, {0x05, 0xa0, 0x8c}, 0x03}, + {PRO_DMOD, 0x00f8, {0x03, 0x06, 0x06}, 0x03}, + {PRO_DMOD, 0x00fc, { 0x03, 0x03, 0x02, 0x08, 0x50, 0x7b, 0x8c, + 0x01, 0x02, 0xc8, 0x00}, 0x0b}, + {PRO_DMOD, 0x0109, {0x02}, 0x01}, + {PRO_DMOD, 0x0115, {0x0a, 0x03}, 0x02}, + {PRO_DMOD, 0x011a, {0xc6}, 0x01}, + {PRO_DMOD, 0x0124, {0xa8}, 0x01}, + {PRO_DMOD, 0x0127, {0x00}, 0x01}, + {PRO_DMOD, 0x012a, {0x59, 0x50, 0x47, 0x42}, 0x04}, + {PRO_DMOD, 0x0137, {0x00}, 0x01}, + {PRO_DMOD, 0x013b, {0x05}, 0x01}, + {PRO_DMOD, 0x013f, {0x5b}, 0x01}, + {PRO_DMOD, 0x0141, { 0x59, 0xf9, 0x59, 0x59, 0x8c, 0x8c, 0x8c, + 0x7b, 0x8c, 0x50, 0x8c, 0x8c, 0xa8, 0xc6, + 0x33}, 0x0f}, + {PRO_DMOD, 0x0151, {0x28}, 0x01}, + {PRO_DMOD, 0x0153, {0xcc}, 0x01}, + {PRO_DMOD, 0x0178, {0x09}, 0x01}, + {PRO_DMOD, 0x0181, {0x9c, 0x76}, 0x02}, + {PRO_DMOD, 0x0185, {0x28}, 0x01}, + {PRO_DMOD, 0x0187, {0x01, 0x00, 0xaa, 0x02, 0x80}, 0x05}, + {PRO_DMOD, 0xed02, {0xff}, 0x01}, + {PRO_DMOD, 0xee42, {0xff}, 0x01}, + {PRO_DMOD, 0xee82, {0xff}, 0x01}, + {PRO_DMOD, 0xf000, {0x0f}, 0x01}, + {PRO_DMOD, 0xf01f, {0x8c, 0x00}, 0x02}, + {PRO_DMOD, 0xf029, {0x8c, 0x00, 0x00}, 0x03}, + {PRO_DMOD, 0xf064, {0x03, 0xf9, 0x03, 0x01}, 0x04}, + {PRO_DMOD, 0xf06f, {0xe0, 0x03}, 0x02}, + {PRO_DMOD, 0xf072, {0x0f, 0x03}, 0x02}, + {PRO_DMOD, 0xf077, {0x01, 0x00}, 0x02}, + {PRO_DMOD, 0xf087, {0x00}, 0x01}, + {PRO_DMOD, 0xf09b, {0x3f, 0x00, 0x20, 0x00, 0x0c, 0x00}, 0x06}, + {PRO_DMOD, 0xf130, {0x04}, 0x01}, + {PRO_DMOD, 0xf132, {0x04}, 0x01}, + {PRO_DMOD, 0xf144, {0x1a}, 0x01}, + {PRO_DMOD, 0xf146, {0x00}, 0x01}, + {PRO_DMOD, 0xf14a, {0x01}, 0x01}, + {PRO_DMOD, 0xf14c, {0x00, 0x00}, 0x02}, + {PRO_DMOD, 0xf14f, {0x04}, 0x01}, + {PRO_DMOD, 0xf158, {0x7f}, 0x01}, + {PRO_DMOD, 0xf15a, {0x00, 0x08}, 0x02}, + {PRO_DMOD, 0xf15d, {0x03, 0x05}, 0x02}, + {PRO_DMOD, 0xf163, {0x05}, 0x01}, + {PRO_DMOD, 0xf166, {0x01, 0x40, 0x0f}, 0x03}, + {PRO_DMOD, 0xf17a, {0x00, 0x00}, 0x02}, + {PRO_DMOD, 0xf183, {0x01}, 0x01}, + {PRO_DMOD, 0xf19d, {0x40}, 0x01}, + {PRO_DMOD, 0xf1bc, {0x36, 0x00}, 0x02}, + {PRO_DMOD, 0xf1cb, {0xa0, 0x01}, 0x02}, + {PRO_DMOD, 0xf204, {0x10}, 0x01}, + {PRO_DMOD, 0xf214, {0x00}, 0x01}, + {PRO_DMOD, 0xf24c, {0x88, 0x95, 0x9a, 0x90}, 0x04}, + {PRO_DMOD, 0xf25a, {0x07, 0xe8, 0x03, 0xb0, 0x04}, 0x05}, + {PRO_DMOD, 0xf270, {0x01, 0x02, 0x01, 0x02}, 0x04}, + {PRO_DMOD, 0xf40e, {0x0a, 0x40, 0x08}, 0x03}, + {PRO_DMOD, 0xf55f, {0x0a}, 0x01}, + {PRO_DMOD, 0xf561, {0x15, 0x20}, 0x02}, + {PRO_DMOD, 0xf5e3, {0x09, 0x01, 0x01}, 0x03}, + {PRO_DMOD, 0xf600, { 0x05, 0x08, 0x0b, 0x0e, 0x11, 0x14, 0x17, + 0x1f}, 0x08}, + {PRO_DMOD, 0xf60e, {0x00, 0x04, 0x32, 0x10}, 0x04}, + {PRO_DMOD, 0xf707, {0xfc, 0x00, 0x37, 0x00}, 0x04}, + {PRO_DMOD, 0xf78b, {0x01}, 0x01}, + {PRO_DMOD, 0xf80f, {0x40, 0x54, 0x5a}, 0x03}, + {PRO_DMOD, 0xf905, {0x01}, 0x01}, + {PRO_DMOD, 0xfb06, {0x03}, 0x01}, + {PRO_DMOD, 0xfd8b, {0x00}, 0x01}, + {0xff, 0x0000, {0x00}, 0x00} /* Terminating Entry */ +}; + +static struct it913xset it9135_62[] = { + {PRO_DMOD, 0x0043, {0x00}, 0x01}, + {PRO_DMOD, 0x0046, {0x62}, 0x01}, + {PRO_DMOD, 0x0051, {0x01}, 0x01}, + {PRO_DMOD, 0x005f, {0x00, 0x00}, 0x02}, + {PRO_DMOD, 0x0068, {0x0a}, 0x01}, + {PRO_DMOD, 0x006a, {0x03}, 0x01}, + {PRO_DMOD, 0x0070, {0x0a, 0x05, 0x02}, 0x03}, + {PRO_DMOD, 0x0075, {0x8c, 0x8c, 0x8c, 0x8c, 0x01}, 0x05}, + {PRO_DMOD, 0x007e, {0x04}, 0x01}, + {PRO_DMOD, 0x0081, {0x0a, 0x12}, 0x02}, + {PRO_DMOD, 0x0084, { 0x0a, 0x33, 0xb8, 0x9c, 0xb2, 0xa6, 0x01}, + 0x07}, + {PRO_DMOD, 0x008e, {0x01}, 0x01}, + {PRO_DMOD, 0x0092, {0x06, 0x00, 0x00, 0x00, 0x00}, 0x05}, + {PRO_DMOD, 0x0099, {0x01}, 0x01}, + {PRO_DMOD, 0x009b, {0x3c, 0x28}, 0x02}, + {PRO_DMOD, 0x009f, {0xe1, 0xcf}, 0x02}, + {PRO_DMOD, 0x00a3, {0x01, 0x5a, 0x01, 0x01}, 0x04}, + {PRO_DMOD, 0x00a9, {0x00, 0x01}, 0x02}, + {PRO_DMOD, 0x00b0, {0x01}, 0x01}, + {PRO_DMOD, 0x00b3, {0x02, 0x3a}, 0x02}, + {PRO_DMOD, 0x00b6, {0x14}, 0x01}, + {PRO_DMOD, 0x00c0, {0x11, 0x00, 0x05, 0x01, 0x00}, 0x05}, + {PRO_DMOD, 0x00c6, {0x19, 0x00}, 0x02}, + {PRO_DMOD, 0x00cb, {0x32, 0x2c, 0x4f, 0x30}, 0x04}, + {PRO_DMOD, 0x00f3, {0x05, 0x8c, 0x8c}, 0x03}, + {PRO_DMOD, 0x00f8, {0x03, 0x06, 0x06}, 0x03}, + {PRO_DMOD, 0x00fc, { 0x02, 0x03, 0x02, 0x09, 0x50, 0x6e, 0x8c, + 0x02, 0x02, 0xc2, 0x00}, 0x0b}, + {PRO_DMOD, 0x0109, {0x02}, 0x01}, + {PRO_DMOD, 0x0115, {0x0a, 0x03}, 0x02}, + {PRO_DMOD, 0x011a, {0xb8}, 0x01}, + {PRO_DMOD, 0x0124, {0xa8}, 0x01}, + {PRO_DMOD, 0x0127, {0x00}, 0x01}, + {PRO_DMOD, 0x012a, {0x53, 0x51, 0x4e, 0x43}, 0x04}, + {PRO_DMOD, 0x0137, {0x00}, 0x01}, + {PRO_DMOD, 0x013b, {0x05}, 0x01}, + {PRO_DMOD, 0x013f, {0x5b}, 0x01}, + {PRO_DMOD, 0x0141, { 0x59, 0xf9, 0x59, 0x19, 0x8c, 0x8c, 0x8c, + 0x7b, 0x8c, 0x50, 0x70, 0x8c, 0x96, 0xd0, + 0x33}, 0x0f}, + {PRO_DMOD, 0x0151, {0x28}, 0x01}, + {PRO_DMOD, 0x0153, {0xb2}, 0x01}, + {PRO_DMOD, 0x0178, {0x09}, 0x01}, + {PRO_DMOD, 0x0181, {0x9c, 0x6e}, 0x02}, + {PRO_DMOD, 0x0185, {0x24}, 0x01}, + {PRO_DMOD, 0x0187, {0x00, 0x00, 0xb8, 0x02, 0x80}, 0x05}, + {PRO_DMOD, 0xed02, {0xff}, 0x01}, + {PRO_DMOD, 0xee42, {0xff}, 0x01}, + {PRO_DMOD, 0xee82, {0xff}, 0x01}, + {PRO_DMOD, 0xf000, {0x0f}, 0x01}, + {PRO_DMOD, 0xf01f, {0x8c, 0x00}, 0x02}, + {PRO_DMOD, 0xf029, {0x8c, 0x00, 0x00}, 0x03}, + {PRO_DMOD, 0xf064, {0x03, 0xf9, 0x03, 0x01}, 0x04}, + {PRO_DMOD, 0xf06f, {0xe0, 0x03}, 0x02}, + {PRO_DMOD, 0xf072, {0x0f, 0x03}, 0x02}, + {PRO_DMOD, 0xf077, {0x01, 0x00}, 0x02}, + {PRO_DMOD, 0xf087, {0x00}, 0x01}, + {PRO_DMOD, 0xf09b, {0x3f, 0x00, 0x20, 0x00, 0x0c, 0x00}, 0x06}, + {PRO_DMOD, 0xf130, {0x04}, 0x01}, + {PRO_DMOD, 0xf132, {0x04}, 0x01}, + {PRO_DMOD, 0xf144, {0x1a}, 0x01}, + {PRO_DMOD, 0xf146, {0x00}, 0x01}, + {PRO_DMOD, 0xf14a, {0x01}, 0x01}, + {PRO_DMOD, 0xf14c, {0x00, 0x00}, 0x02}, + {PRO_DMOD, 0xf14f, {0x04}, 0x01}, + {PRO_DMOD, 0xf158, {0x7f}, 0x01}, + {PRO_DMOD, 0xf15a, {0x00, 0x08}, 0x02}, + {PRO_DMOD, 0xf15d, {0x03, 0x05}, 0x02}, + {PRO_DMOD, 0xf163, {0x05}, 0x01}, + {PRO_DMOD, 0xf166, {0x01, 0x40, 0x0f}, 0x03}, + {PRO_DMOD, 0xf17a, {0x00, 0x00}, 0x02}, + {PRO_DMOD, 0xf183, {0x01}, 0x01}, + {PRO_DMOD, 0xf19d, {0x40}, 0x01}, + {PRO_DMOD, 0xf1bc, {0x36, 0x00}, 0x02}, + {PRO_DMOD, 0xf1cb, {0xa0, 0x01}, 0x02}, + {PRO_DMOD, 0xf204, {0x10}, 0x01}, + {PRO_DMOD, 0xf214, {0x00}, 0x01}, + {PRO_DMOD, 0xf24c, {0x88, 0x95, 0x9a, 0x90}, 0x04}, + {PRO_DMOD, 0xf25a, {0x07, 0xe8, 0x03, 0xb0, 0x04}, 0x05}, + {PRO_DMOD, 0xf270, {0x01, 0x02, 0x01, 0x02}, 0x04}, + {PRO_DMOD, 0xf40e, {0x0a, 0x40, 0x08}, 0x03}, + {PRO_DMOD, 0xf55f, {0x0a}, 0x01}, + {PRO_DMOD, 0xf561, {0x15, 0x20}, 0x02}, + {PRO_DMOD, 0xf5e3, {0x09, 0x01, 0x01}, 0x03}, + {PRO_DMOD, 0xf600, { 0x05, 0x08, 0x0b, 0x0e, 0x11, 0x14, 0x17, + 0x1f}, 0x08}, + {PRO_DMOD, 0xf60e, {0x00, 0x04, 0x32, 0x10}, 0x04}, + {PRO_DMOD, 0xf707, {0xfc, 0x00, 0x37, 0x00}, 0x04}, + {PRO_DMOD, 0xf78b, {0x01}, 0x01}, + {PRO_DMOD, 0xf80f, {0x40, 0x54, 0x5a}, 0x03}, + {PRO_DMOD, 0xf905, {0x01}, 0x01}, + {PRO_DMOD, 0xfb06, {0x03}, 0x01}, + {PRO_DMOD, 0xfd8b, {0x00}, 0x01}, + {0xff, 0x0000, {0x00}, 0x00} /* Terminating Entry */ }; +/* Tuner setting scripts (still keeping it9137) */ static struct it913xset it9137_tuner_off[] = { {PRO_DMOD, 0xfba8, {0x01}, 0x01}, /* Tuner Clock Off */ {PRO_DMOD, 0xec40, {0x00}, 0x01}, /* Power Down Tuner */ diff --git a/drivers/media/dvb/frontends/it913x-fe.c b/drivers/media/dvb/frontends/it913x-fe.c index d4bd24e..5113b89 100644 --- a/drivers/media/dvb/frontends/it913x-fe.c +++ b/drivers/media/dvb/frontends/it913x-fe.c @@ -50,6 +50,7 @@ MODULE_PARM_DESC(debug, "set debugging level (1=info (or-able))."); struct it913x_fe_state { struct dvb_frontend frontend; struct i2c_adapter *i2c_adap; + struct ite_config *config; u8 i2c_addr; u32 frequency; u8 adf; @@ -211,13 +212,17 @@ static int it913x_init_tuner(struct it913x_fe_state *state) state->tun_fn_min /= (state->tun_fdiv * nv_val); deb_info("Tuner fn_min %d", state->tun_fn_min); - for (i = 0; i < 50; i++) { - reg = it913x_read_reg_u8(state, 0xec82); - if (reg > 0) - break; - if (reg < 0) - return -ENODEV; - udelay(2000); + if (state->config->chip_ver > 1) + msleep(50); + else { + for (i = 0; i < 50; i++) { + reg = it913x_read_reg_u8(state, 0xec82); + if (reg > 0) + break; + if (reg < 0) + return -ENODEV; + udelay(2000); + } } return it913x_write_reg(state, PRO_DMOD, 0xed81, val); @@ -578,7 +583,12 @@ static int it913x_fe_set_frontend(struct dvb_frontend *fe, deb_info("Frontend Set Tuner Type %02x", state->tuner_type); switch (state->tuner_type) { - case IT9137: /* Tuner type 0x38 */ + case IT9135_38: + case IT9135_51: + case IT9135_52: + case IT9135_60: + case IT9135_61: + case IT9135_62: ret = it9137_set_tuner(state, p->u.ofdm.bandwidth, p->frequency); break; @@ -678,14 +688,15 @@ static u32 compute_div(u32 a, u32 b, u32 x) static int it913x_fe_start(struct it913x_fe_state *state) { - struct it913xset *set_fe; + struct it913xset *set_lna; struct it913xset *set_mode; int ret; - u8 adf = (state->adf & 0xf); + u8 adf = (state->config->adf & 0xf); u32 adc, xtal; u8 b[4]; - ret = it913x_init_tuner(state); + if (state->config->chip_ver == 1) + ret = it913x_init_tuner(state); if (adf < 12) { state->crystalFrequency = fe_clockTable[adf].xtal ; @@ -720,23 +731,57 @@ static int it913x_fe_start(struct it913x_fe_state *state) b[1] = (adc >> 8) & 0xff; b[2] = (adc >> 16) & 0xff; ret |= it913x_write(state, PRO_DMOD, ADC_FREQ, b, 3); + if (ret < 0) + return -ENODEV; + /* v1 or v2 tuner script */ + if (state->config->chip_ver > 1) + ret = it913x_fe_script_loader(state, it9135_v2); + else + ret = it913x_fe_script_loader(state, it9135_v1); + if (ret < 0) + return ret; + + /* LNA Scripts */ switch (state->tuner_type) { - case IT9137: /* Tuner type 0x38 */ - set_fe = it9137_set; + case IT9135_51: + set_lna = it9135_51; + break; + case IT9135_52: + set_lna = it9135_52; break; + case IT9135_60: + set_lna = it9135_60; + break; + case IT9135_61: + set_lna = it9135_61; + break; + case IT9135_62: + set_lna = it9135_62; + break; + case IT9135_38: default: - return -EINVAL; + set_lna = it9135_38; } + ret = it913x_fe_script_loader(state, set_lna); + if (ret < 0) + return ret; + + if (state->config->chip_ver == 2) { + ret = it913x_write_reg(state, PRO_DMOD, TRIGGER_OFSM, 0x1); + ret |= it913x_write_reg(state, PRO_LINK, PADODPU, 0x0); + ret |= it913x_write_reg(state, PRO_LINK, AGC_O_D, 0x0); + ret |= it913x_init_tuner(state); + } + if (ret < 0) + return -ENODEV; - /* set the demod */ - ret = it913x_fe_script_loader(state, set_fe); /* Always solo frontend */ set_mode = set_solo_fe; ret |= it913x_fe_script_loader(state, set_mode); ret |= it913x_fe_suspend(state); - return 0; + return (ret < 0) ? -ENODEV : 0; } static int it913x_fe_init(struct dvb_frontend *fe) @@ -750,13 +795,7 @@ static int it913x_fe_init(struct dvb_frontend *fe) ret |= it913x_fe_script_loader(state, init_1); - switch (state->tuner_type) { - case IT9137: - ret |= it913x_write_reg(state, PRO_DMOD, 0xfba8, 0x0); - break; - default: - return -EINVAL; - } + ret |= it913x_write_reg(state, PRO_DMOD, 0xfba8, 0x0); return (ret < 0) ? -ENODEV : 0; } @@ -770,19 +809,34 @@ static void it913x_fe_release(struct dvb_frontend *fe) static struct dvb_frontend_ops it913x_fe_ofdm_ops; struct dvb_frontend *it913x_fe_attach(struct i2c_adapter *i2c_adap, - u8 i2c_addr, u8 adf, u8 type) + u8 i2c_addr, struct ite_config *config) { struct it913x_fe_state *state = NULL; int ret; + /* allocate memory for the internal state */ state = kzalloc(sizeof(struct it913x_fe_state), GFP_KERNEL); if (state == NULL) + return NULL; + if (config == NULL) goto error; state->i2c_adap = i2c_adap; state->i2c_addr = i2c_addr; - state->adf = adf; - state->tuner_type = type; + state->config = config; + + switch (state->config->tuner_id_0) { + case IT9135_51: + case IT9135_52: + case IT9135_60: + case IT9135_61: + case IT9135_62: + state->tuner_type = state->config->tuner_id_0; + break; + default: + case IT9135_38: + state->tuner_type = IT9135_38; + } ret = it913x_fe_start(state); if (ret < 0) @@ -835,5 +889,5 @@ static struct dvb_frontend_ops it913x_fe_ofdm_ops = { MODULE_DESCRIPTION("it913x Frontend and it9137 tuner"); MODULE_AUTHOR("Malcolm Priestley tvboxspy@gmail.com"); -MODULE_VERSION("1.07"); +MODULE_VERSION("1.08"); MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/frontends/it913x-fe.h b/drivers/media/dvb/frontends/it913x-fe.h index 9d97f32..43f879a 100644 --- a/drivers/media/dvb/frontends/it913x-fe.h +++ b/drivers/media/dvb/frontends/it913x-fe.h @@ -23,13 +23,25 @@ #include #include "dvb_frontend.h" + +struct ite_config { + u8 chip_ver; + u16 chip_type; + u32 firmware; + u8 tuner_id_0; + u8 tuner_id_1; + u8 dual_mode; + u8 adf; +}; + #if defined(CONFIG_DVB_IT913X_FE) || (defined(CONFIG_DVB_IT913X_FE_MODULE) && \ defined(MODULE)) extern struct dvb_frontend *it913x_fe_attach(struct i2c_adapter *i2c_adap, - u8 i2c_addr, u8 adf, u8 type); + u8 i2c_addr, struct ite_config *config); #else static inline struct dvb_frontend *it913x_fe_attach( - struct i2c_adapter *i2c_adap, u8 i2c_addr, u8 adf, u8 type) + struct i2c_adapter *i2c_adap, + u8 i2c_addr, struct ite_config *config) { printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); return NULL; @@ -144,8 +156,14 @@ static inline struct dvb_frontend *it913x_fe_attach( #define EST_SIGNAL_LEVEL 0x004a #define FREE_BAND 0x004b #define SUSPEND_FLAG 0x004c -/* Build in tuners */ +/* Build in tuner types */ #define IT9137 0x38 +#define IT9135_38 0x38 +#define IT9135_51 0x50 +#define IT9135_52 0x52 +#define IT9135_60 0x60 +#define IT9135_61 0x61 +#define IT9135_62 0x62 enum { CMD_DEMOD_READ = 0, -- cgit v0.10.2 From 2b3c13ecce3bc0fbdeb5ef0596b350dc702d01d5 Mon Sep 17 00:00:00 2001 From: tvboxspy Date: Mon, 31 Oct 2011 12:06:34 -0300 Subject: [media] it913x-fe ver 1.09 amend adc table entries Amend adc table entries and size. Signed-off-by: Malcolm Priestley Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/dvb/frontends/it913x-fe-priv.h b/drivers/media/dvb/frontends/it913x-fe-priv.h index abf1395..836a5b8 100644 --- a/drivers/media/dvb/frontends/it913x-fe-priv.h +++ b/drivers/media/dvb/frontends/it913x-fe-priv.h @@ -153,8 +153,7 @@ struct table { }; static struct table fe_clockTable[] = { - {12000000, tab3}, /* FPGA */ - {16384000, tab6}, /* 16.38MHz */ + {12000000, tab3}, /* 12.00MHz */ {20480000, tab6}, /* 20.48MHz */ {36000000, tab3}, /* 36.00MHz */ {30000000, tab1}, /* 30.00MHz */ @@ -164,7 +163,6 @@ static struct table fe_clockTable[] = { {34000000, tab2}, /* 34.00MHz */ {24000000, tab1}, /* 24.00MHz */ {22000000, tab8}, /* 22.00MHz */ - {12000000, tab3} /* 12.00MHz */ }; /* fe get */ diff --git a/drivers/media/dvb/frontends/it913x-fe.c b/drivers/media/dvb/frontends/it913x-fe.c index 5113b89..6d12dcc 100644 --- a/drivers/media/dvb/frontends/it913x-fe.c +++ b/drivers/media/dvb/frontends/it913x-fe.c @@ -53,7 +53,6 @@ struct it913x_fe_state { struct ite_config *config; u8 i2c_addr; u32 frequency; - u8 adf; u32 crystalFrequency; u32 adcFrequency; u8 tuner_type; @@ -698,7 +697,7 @@ static int it913x_fe_start(struct it913x_fe_state *state) if (state->config->chip_ver == 1) ret = it913x_init_tuner(state); - if (adf < 12) { + if (adf < 10) { state->crystalFrequency = fe_clockTable[adf].xtal ; state->table = fe_clockTable[adf].table; state->adcFrequency = state->table->adcFrequency; @@ -889,5 +888,5 @@ static struct dvb_frontend_ops it913x_fe_ofdm_ops = { MODULE_DESCRIPTION("it913x Frontend and it9137 tuner"); MODULE_AUTHOR("Malcolm Priestley tvboxspy@gmail.com"); -MODULE_VERSION("1.08"); +MODULE_VERSION("1.09"); MODULE_LICENSE("GPL"); -- cgit v0.10.2 From ff17999184ed13829bc14c3be412d980173dff40 Mon Sep 17 00:00:00 2001 From: Josh Boyer Date: Wed, 2 Nov 2011 16:39:58 -0300 Subject: [media] ttusb2: Don't use stack variables for DMA The ttusb2_msg function uses on-stack variables to submit commands to dvb_usb_generic. This eventually gets to the DMA api layer and will throw a traceback if the debugging options are set. This allocates the temporary buffer variables with kzalloc instead. Fixes https://bugzilla.redhat.com/show_bug.cgi?id=734506 Signed-off-by: Josh Boyer Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/dvb/dvb-usb/ttusb2.c b/drivers/media/dvb/dvb-usb/ttusb2.c index ea4eab8..faed393 100644 --- a/drivers/media/dvb/dvb-usb/ttusb2.c +++ b/drivers/media/dvb/dvb-usb/ttusb2.c @@ -75,10 +75,18 @@ static int ttusb2_msg(struct dvb_usb_device *d, u8 cmd, u8 *wbuf, int wlen, u8 *rbuf, int rlen) { struct ttusb2_state *st = d->priv; - u8 s[wlen+4],r[64] = { 0 }; + u8 *s, *r = NULL; int ret = 0; - memset(s,0,wlen+4); + s = kzalloc(wlen+4, GFP_KERNEL); + if (!s) + return -ENOMEM; + + r = kzalloc(64, GFP_KERNEL); + if (!r) { + kfree(s); + return -ENOMEM; + } s[0] = 0xaa; s[1] = ++st->id; @@ -94,12 +102,17 @@ static int ttusb2_msg(struct dvb_usb_device *d, u8 cmd, r[2] != cmd || (rlen > 0 && r[3] != rlen)) { warn("there might have been an error during control message transfer. (rlen = %d, was %d)",rlen,r[3]); + kfree(s); + kfree(r); return -EIO; } if (rlen > 0) memcpy(rbuf, &r[4], rlen); + kfree(s); + kfree(r); + return 0; } -- cgit v0.10.2 From f8e6defe7f4456d8700e5a3796a1e9fb54a88543 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Fri, 28 Oct 2011 08:40:00 +1100 Subject: Update NFSD MAINTAINER Neil hasn't really been at all active as a maintainer for some years now. So move his maintainership to CREDITS Signed-off-by: NeilBrown Signed-off-by: J. Bruce Fields diff --git a/CREDITS b/CREDITS index 07e32a87..557da47 100644 --- a/CREDITS +++ b/CREDITS @@ -514,6 +514,11 @@ S: Bessemerstraat 21 S: Amsterdam S: The Netherlands +N: NeilBrown +E: neil@brown.name +P: 4096R/566281B9 1BC6 29EB D390 D870 7B5F 497A 39EC 9EDD 5662 81B9 +D: NFSD Maintainer 2000-2007 + N: Zach Brown E: zab@zabbo.net D: maestro pci sound diff --git a/MAINTAINERS b/MAINTAINERS index 4808256..6ab923d 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3770,7 +3770,6 @@ S: Odd Fixes KERNEL NFSD, SUNRPC, AND LOCKD SERVERS M: "J. Bruce Fields" -M: Neil Brown L: linux-nfs@vger.kernel.org W: http://nfs.sourceforge.net/ S: Supported -- cgit v0.10.2 From b93d87c19821ba7d3ee11557403d782e541071ad Mon Sep 17 00:00:00 2001 From: "J. Bruce Fields" Date: Mon, 7 Nov 2011 16:37:57 -0500 Subject: nfsd4: fix lockowner matching Lockowners are looked up by file as well as by owner, but we were forgetting to do a comparison on the file. This could cause an incorrect result from lockt. (Note looking up the inode from the lockowner is pretty awkward here. The data structures need fixing.) Cc: stable@kernel.org Signed-off-by: J. Bruce Fields diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 47e94e3..5abced7 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -3809,16 +3809,29 @@ nevermind: deny->ld_type = NFS4_WRITE_LT; } +static bool same_lockowner_ino(struct nfs4_lockowner *lo, struct inode *inode, clientid_t *clid, struct xdr_netobj *owner) +{ + struct nfs4_ol_stateid *lst; + + if (!same_owner_str(&lo->lo_owner, owner, clid)) + return false; + lst = list_first_entry(&lo->lo_owner.so_stateids, + struct nfs4_ol_stateid, st_perstateowner); + return lst->st_file->fi_inode == inode; +} + static struct nfs4_lockowner * find_lockowner_str(struct inode *inode, clientid_t *clid, struct xdr_netobj *owner) { unsigned int hashval = lock_ownerstr_hashval(inode, clid->cl_id, owner); + struct nfs4_lockowner *lo; struct nfs4_stateowner *op; list_for_each_entry(op, &lock_ownerstr_hashtbl[hashval], so_strhash) { - if (same_owner_str(op, owner, clid)) - return lockowner(op); + lo = lockowner(op); + if (same_lockowner_ino(lo, inode, clid, owner)) + return lo; } return NULL; } -- cgit v0.10.2 From 684e563858018d27acb8f00e30c026215bbd0ffb Mon Sep 17 00:00:00 2001 From: "J. Bruce Fields" Date: Fri, 4 Nov 2011 17:08:10 -0400 Subject: nfsd4: cleanup lock clientid handling in sessions case I'd rather the "ignore clientid in sessions case" rule be enforced in just one place. Signed-off-by: J. Bruce Fields diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 5abced7..9354dde 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -3946,10 +3946,15 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, * lock stateid. */ struct nfs4_ol_stateid *open_stp = NULL; - + + if (nfsd4_has_session(cstate)) + /* See rfc 5661 18.10.3: given clientid is ignored: */ + memcpy(&lock->v.new.clientid, + &cstate->session->se_client->cl_clientid, + sizeof(clientid_t)); + status = nfserr_stale_clientid; - if (!nfsd4_has_session(cstate) && - STALE_CLIENTID(&lock->lk_new_clientid)) + if (STALE_CLIENTID(&lock->lk_new_clientid)) goto out; /* validate and update open stateid and open seqid */ @@ -3961,8 +3966,7 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, goto out; open_sop = openowner(open_stp->st_stateowner); status = nfserr_bad_stateid; - if (!nfsd4_has_session(cstate) && - !same_clid(&open_sop->oo_owner.so_client->cl_clientid, + if (!same_clid(&open_sop->oo_owner.so_client->cl_clientid, &lock->v.new.clientid)) goto out; /* create lockowner and lock stateid */ -- cgit v0.10.2 From 64a284d07c7d84299a90826950079a8ef11e8204 Mon Sep 17 00:00:00 2001 From: "J. Bruce Fields" Date: Thu, 20 Oct 2011 06:57:46 -0400 Subject: nfsd4: maintain one seqid stream per (lockowner, file) Instead of creating a new lockowner and stateid for every open_to_lockowner call, reuse the existing lockowner if it exists. Reported-by: Trond Myklebust Signed-off-by: J. Bruce Fields diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 9354dde..d09d524 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -3905,6 +3905,37 @@ static void get_lock_access(struct nfs4_ol_stateid *lock_stp, u32 access) __set_bit(access, &lock_stp->st_access_bmap); } +__be32 lookup_or_create_lock_state(struct nfsd4_compound_state *cstate, struct nfs4_ol_stateid *ost, struct nfsd4_lock *lock, struct nfs4_ol_stateid **lst, bool *new) +{ + struct nfs4_file *fi = ost->st_file; + struct nfs4_openowner *oo = openowner(ost->st_stateowner); + struct nfs4_client *cl = oo->oo_owner.so_client; + struct nfs4_lockowner *lo; + unsigned int strhashval; + + lo = find_lockowner_str(fi->fi_inode, &cl->cl_clientid, &lock->v.new.owner); + if (lo) { + if (!cstate->minorversion) + return nfserr_bad_seqid; + /* XXX: a lockowner always has exactly one stateid: */ + *lst = list_first_entry(&lo->lo_owner.so_stateids, + struct nfs4_ol_stateid, st_perstateowner); + return nfs_ok; + } + strhashval = lock_ownerstr_hashval(fi->fi_inode, cl->cl_clientid.cl_id, + &lock->v.new.owner); + lo = alloc_init_lock_stateowner(strhashval, cl, ost, lock); + if (lo == NULL) + return nfserr_jukebox; + *lst = alloc_init_lock_stateid(lo, fi, ost); + if (*lst == NULL) { + release_lockowner(lo); + return nfserr_jukebox; + } + *new = true; + return nfs_ok; +} + /* * LOCK operation */ @@ -3920,7 +3951,7 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, struct file_lock file_lock; struct file_lock conflock; __be32 status = 0; - unsigned int strhashval; + bool new_state = false; int lkflg; int err; @@ -3969,21 +4000,9 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, if (!same_clid(&open_sop->oo_owner.so_client->cl_clientid, &lock->v.new.clientid)) goto out; - /* create lockowner and lock stateid */ - fp = open_stp->st_file; - strhashval = lock_ownerstr_hashval(fp->fi_inode, - open_sop->oo_owner.so_client->cl_clientid.cl_id, - &lock->v.new.owner); - /* XXX: Do we need to check for duplicate stateowners on - * the same file, or should they just be allowed (and - * create new stateids)? */ - status = nfserr_jukebox; - lock_sop = alloc_init_lock_stateowner(strhashval, - open_sop->oo_owner.so_client, open_stp, lock); - if (lock_sop == NULL) - goto out; - lock_stp = alloc_init_lock_stateid(lock_sop, fp, open_stp); - if (lock_stp == NULL) + status = lookup_or_create_lock_state(cstate, open_stp, lock, + &lock_stp, &new_state); + if (status) goto out; } else { /* lock (lock owner + lock stateid) already exists */ @@ -3993,10 +4012,9 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, NFS4_LOCK_STID, &lock_stp); if (status) goto out; - lock_sop = lockowner(lock_stp->st_stateowner); - fp = lock_stp->st_file; } - /* lock_sop and lock_stp have been created or found */ + lock_sop = lockowner(lock_stp->st_stateowner); + fp = lock_stp->st_file; lkflg = setlkflg(lock->lk_type); status = nfs4_check_openmode(lock_stp, lkflg); @@ -4071,7 +4089,7 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, break; } out: - if (status && lock->lk_is_new && lock_sop) + if (status && new_state) release_lockowner(lock_sop); if (!cstate->replay_owner) nfs4_unlock_state(); -- cgit v0.10.2 From 65178db42a02c7984f711614546e97e9952d8e01 Mon Sep 17 00:00:00 2001 From: Bryan Schumaker Date: Tue, 1 Nov 2011 13:35:21 -0400 Subject: NFSD: Added fault injection Fault injection on the NFS server makes it easier to test the client's state manager and recovery threads. Simulating errors on the server is easier than finding the right conditions that cause them naturally. This patch uses debugfs to add a simple framework for fault injection to the server. This framework is a config option, and can be enabled through CONFIG_NFSD_FAULT_INJECTION. Assuming you have debugfs mounted to /sys/debug, a set of files will be created in /sys/debug/nfsd/. Writing to any of these files will cause the corresponding action and write a log entry to dmesg. Signed-off-by: Bryan Schumaker Signed-off-by: J. Bruce Fields diff --git a/fs/nfsd/Kconfig b/fs/nfsd/Kconfig index 10e6366..8df1ea4 100644 --- a/fs/nfsd/Kconfig +++ b/fs/nfsd/Kconfig @@ -80,3 +80,13 @@ config NFSD_V4 available from http://linux-nfs.org/. If unsure, say N. + +config NFSD_FAULT_INJECTION + bool "NFS server manual fault injection" + depends on NFSD_V4 && DEBUG_KERNEL + help + This option enables support for manually injecting faults + into the NFS server. This is intended to be used for + testing error recovery on the NFS client. + + If unsure, say N. diff --git a/fs/nfsd/Makefile b/fs/nfsd/Makefile index 9b118ee..af32ef0 100644 --- a/fs/nfsd/Makefile +++ b/fs/nfsd/Makefile @@ -6,6 +6,7 @@ obj-$(CONFIG_NFSD) += nfsd.o nfsd-y := nfssvc.o nfsctl.o nfsproc.o nfsfh.o vfs.o \ export.o auth.o lockd.o nfscache.o nfsxdr.o stats.o +nfsd-$(CONFIG_NFSD_FAULT_INJECTION) += fault_inject.o nfsd-$(CONFIG_NFSD_V2_ACL) += nfs2acl.o nfsd-$(CONFIG_NFSD_V3) += nfs3proc.o nfs3xdr.o nfsd-$(CONFIG_NFSD_V3_ACL) += nfs3acl.o diff --git a/fs/nfsd/fault_inject.c b/fs/nfsd/fault_inject.c new file mode 100644 index 0000000..ce7f075 --- /dev/null +++ b/fs/nfsd/fault_inject.c @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2011 Bryan Schumaker + * + * Uses debugfs to create fault injection points for client testing + */ + +#include +#include +#include +#include + +#include "state.h" +#include "fault_inject.h" + +struct nfsd_fault_inject_op { + char *file; + void (*func)(u64); +}; + +static struct nfsd_fault_inject_op inject_ops[] = { + { + .file = "forget_clients", + .func = nfsd_forget_clients, + }, + { + .file = "forget_locks", + .func = nfsd_forget_locks, + }, + { + .file = "forget_openowners", + .func = nfsd_forget_openowners, + }, + { + .file = "forget_delegations", + .func = nfsd_forget_delegations, + }, + { + .file = "recall_delegations", + .func = nfsd_recall_delegations, + }, +}; + +static long int NUM_INJECT_OPS = sizeof(inject_ops) / sizeof(struct nfsd_fault_inject_op); +static struct dentry *debug_dir; + +static int nfsd_inject_set(void *op_ptr, u64 val) +{ + struct nfsd_fault_inject_op *op = op_ptr; + + if (val == 0) + printk(KERN_INFO "NFSD Fault Injection: %s (all)", op->file); + else + printk(KERN_INFO "NFSD Fault Injection: %s (n = %llu)", op->file, val); + + op->func(val); + return 0; +} + +static int nfsd_inject_get(void *data, u64 *val) +{ + return 0; +} + +DEFINE_SIMPLE_ATTRIBUTE(fops_nfsd, nfsd_inject_get, nfsd_inject_set, "%llu\n"); + +void nfsd_fault_inject_cleanup(void) +{ + debugfs_remove_recursive(debug_dir); +} + +int nfsd_fault_inject_init(void) +{ + unsigned int i; + struct nfsd_fault_inject_op *op; + mode_t mode = S_IFREG | S_IRUSR | S_IWUSR; + + debug_dir = debugfs_create_dir("nfsd", NULL); + if (!debug_dir) + goto fail; + + for (i = 0; i < NUM_INJECT_OPS; i++) { + op = &inject_ops[i]; + if (!debugfs_create_file(op->file, mode, debug_dir, op, &fops_nfsd)) + goto fail; + } + return 0; + +fail: + nfsd_fault_inject_cleanup(); + return -ENOMEM; +} diff --git a/fs/nfsd/fault_inject.h b/fs/nfsd/fault_inject.h new file mode 100644 index 0000000..90bd057 --- /dev/null +++ b/fs/nfsd/fault_inject.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2011 Bryan Schumaker + * + * Function definitions for fault injection + */ + +#ifndef LINUX_NFSD_FAULT_INJECT_H +#define LINUX_NFSD_FAULT_INJECT_H + +#ifdef CONFIG_NFSD_FAULT_INJECTION +int nfsd_fault_inject_init(void); +void nfsd_fault_inject_cleanup(void); +void nfsd_forget_clients(u64); +void nfsd_forget_locks(u64); +void nfsd_forget_openowners(u64); +void nfsd_forget_delegations(u64); +void nfsd_recall_delegations(u64); +#else /* CONFIG_NFSD_FAULT_INJECTION */ +static inline int nfsd_fault_inject_init(void) { return 0; } +static inline void nfsd_fault_inject_cleanup(void) {} +static inline void nfsd_forget_clients(u64 num) {} +static inline void nfsd_forget_locks(u64 num) {} +static inline void nfsd_forget_openowners(u64 num) {} +static inline void nfsd_forget_delegations(u64 num) {} +static inline void nfsd_recall_delegations(u64 num) {} +#endif /* CONFIG_NFSD_FAULT_INJECTION */ + +#endif /* LINUX_NFSD_FAULT_INJECT_H */ diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index d09d524..a511eff 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -4429,6 +4429,121 @@ nfs4_check_open_reclaim(clientid_t *clid) return nfs4_find_reclaim_client(clid) ? nfs_ok : nfserr_reclaim_bad; } +#ifdef CONFIG_NFSD_FAULT_INJECTION + +void nfsd_forget_clients(u64 num) +{ + struct nfs4_client *clp, *next; + int count = 0; + + nfs4_lock_state(); + list_for_each_entry_safe(clp, next, &client_lru, cl_lru) { + nfsd4_remove_clid_dir(clp); + expire_client(clp); + if (++count == num) + break; + } + nfs4_unlock_state(); + + printk(KERN_INFO "NFSD: Forgot %d clients", count); +} + +static void release_lockowner_sop(struct nfs4_stateowner *sop) +{ + release_lockowner(lockowner(sop)); +} + +static void release_openowner_sop(struct nfs4_stateowner *sop) +{ + release_openowner(openowner(sop)); +} + +static int nfsd_release_n_owners(u64 num, + struct list_head hashtbl[], + unsigned int hashtbl_size, + void (*release_sop)(struct nfs4_stateowner *)) +{ + int i, count = 0; + struct nfs4_stateowner *sop, *next; + + for (i = 0; i < hashtbl_size; i++) { + list_for_each_entry_safe(sop, next, &hashtbl[i], so_strhash) { + release_sop(sop); + if (++count == num) + return count; + } + } + return count; +} + +void nfsd_forget_locks(u64 num) +{ + int count; + + nfs4_lock_state(); + count = nfsd_release_n_owners(num, lock_ownerstr_hashtbl, + LOCK_HASH_SIZE, release_lockowner_sop); + nfs4_unlock_state(); + + printk(KERN_INFO "NFSD: Forgot %d locks", count); +} + +void nfsd_forget_openowners(u64 num) +{ + int count; + + nfs4_lock_state(); + count = nfsd_release_n_owners(num, open_ownerstr_hashtbl, + OPEN_OWNER_HASH_SIZE, release_openowner_sop); + nfs4_unlock_state(); + + printk(KERN_INFO "NFSD: Forgot %d open owners", count); +} + +int nfsd_process_n_delegations(u64 num, void (*deleg_func)(struct nfs4_delegation *)) +{ + int i, count = 0; + struct nfs4_file *fp; + struct nfs4_delegation *dp, *next; + + for (i = 0; i < FILE_HASH_SIZE; i++) { + list_for_each_entry(fp, &file_hashtbl[i], fi_hash) { + list_for_each_entry_safe(dp, next, &fp->fi_delegations, dl_perfile) { + deleg_func(dp); + if (++count == num) + return count; + } + } + } + return count; +} + +void nfsd_forget_delegations(u64 num) +{ + unsigned int count; + + nfs4_lock_state(); + count = nfsd_process_n_delegations(num, unhash_delegation); + nfs4_unlock_state(); + + printk(KERN_INFO "NFSD: Forgot %d delegations", count); +} + +void nfsd_recall_delegations(u64 num) +{ + unsigned int count; + + nfs4_lock_state(); + spin_lock(&recall_lock); + count = nfsd_process_n_delegations(num, nfsd_break_one_deleg); + spin_unlock(&recall_lock); + nfs4_unlock_state(); + + printk(KERN_INFO "NFSD: Recalled %d delegations", count); +} + +#endif /* CONFIG_NFSD_FAULT_INJECTION */ + /* initialization to perform at module load time: */ int diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c index c45a2ea..b2e8093 100644 --- a/fs/nfsd/nfsctl.c +++ b/fs/nfsd/nfsctl.c @@ -18,6 +18,7 @@ #include "idmap.h" #include "nfsd.h" #include "cache.h" +#include "fault_inject.h" /* * We have a single directory with several nodes in it. @@ -1131,6 +1132,9 @@ static int __init init_nfsd(void) retval = nfs4_state_init(); /* nfs4 locking state */ if (retval) return retval; + retval = nfsd_fault_inject_init(); /* nfsd fault injection controls */ + if (retval) + goto out_free_slabs; nfsd_stat_init(); /* Statistics */ retval = nfsd_reply_cache_init(); if (retval) @@ -1161,6 +1165,8 @@ out_free_cache: nfsd_reply_cache_shutdown(); out_free_stat: nfsd_stat_shutdown(); + nfsd_fault_inject_cleanup(); +out_free_slabs: nfsd4_free_slabs(); return retval; } @@ -1175,6 +1181,7 @@ static void __exit exit_nfsd(void) nfsd_lockd_shutdown(); nfsd_idmap_shutdown(); nfsd4_free_slabs(); + nfsd_fault_inject_cleanup(); unregister_filesystem(&nfsd_fs_type); } -- cgit v0.10.2 From 800b927b38c7cdfbd7df39d7a8a4b065637ab7b6 Mon Sep 17 00:00:00 2001 From: Bryan Schumaker Date: Tue, 1 Nov 2011 13:35:22 -0400 Subject: NFSD: Added fault injection script This script provides a convenient way to use the NFSD fault injection framework. Fault injection writes to dmesg using the KERN_INFO flag, so this script will compare the before and after output of `dmesg` to show the user what happened Signed-off-by: Bryan Schumaker Signed-off-by: J. Bruce Fields diff --git a/tools/nfsd/inject_fault.sh b/tools/nfsd/inject_fault.sh new file mode 100755 index 0000000..06a399a --- /dev/null +++ b/tools/nfsd/inject_fault.sh @@ -0,0 +1,49 @@ +#!/bin/bash +# +# Copyright (c) 2011 Bryan Schumaker +# +# Script for easier NFSD fault injection + +# Check that debugfs has been mounted +DEBUGFS=`cat /proc/mounts | grep debugfs` +if [ "$DEBUGFS" == "" ]; then + echo "debugfs does not appear to be mounted!" + echo "Please mount debugfs and try again" + exit 1 +fi + +# Check that the fault injection directory exists +DEBUGDIR=`echo $DEBUGFS | awk '{print $2}'`/nfsd +if [ ! -d "$DEBUGDIR" ]; then + echo "$DEBUGDIR does not exist" + echo "Check that your .config selects CONFIG_NFSD_FAULT_INJECTION" + exit 1 +fi + +function help() +{ + echo "Usage $0 injection_type [count]" + echo "" + echo "Injection types are:" + ls $DEBUGDIR + exit 1 +} + +if [ $# == 0 ]; then + help +elif [ ! -f $DEBUGDIR/$1 ]; then + help +elif [ $# != 2 ]; then + COUNT=0 +else + COUNT=$2 +fi + +BEFORE=`mktemp` +AFTER=`mktemp` +dmesg > $BEFORE +echo $COUNT > $DEBUGDIR/$1 +dmesg > $AFTER +# Capture lines that only exist in the $AFTER file +diff $BEFORE $AFTER | grep ">" +rm -f $BEFORE $AFTER -- cgit v0.10.2 From 114a0a08d46cfb0eefb1a882f7866b7f57bfc5ba Mon Sep 17 00:00:00 2001 From: Bryan Schumaker Date: Tue, 1 Nov 2011 13:35:23 -0400 Subject: NFSD: Added fault injection documentation Signed-off-by: Bryan Schumaker Signed-off-by: J. Bruce Fields diff --git a/Documentation/filesystems/nfs/00-INDEX b/Documentation/filesystems/nfs/00-INDEX index a57e124..1716874a 100644 --- a/Documentation/filesystems/nfs/00-INDEX +++ b/Documentation/filesystems/nfs/00-INDEX @@ -2,6 +2,8 @@ - this file (nfs-related documentation). Exporting - explanation of how to make filesystems exportable. +fault_injection.txt + - information for using fault injection on the server knfsd-stats.txt - statistics which the NFS server makes available to user space. nfs.txt diff --git a/Documentation/filesystems/nfs/fault_injection.txt b/Documentation/filesystems/nfs/fault_injection.txt new file mode 100644 index 0000000..426d166 --- /dev/null +++ b/Documentation/filesystems/nfs/fault_injection.txt @@ -0,0 +1,69 @@ + +Fault Injection +=============== +Fault injection is a method for forcing errors that may not normally occur, or +may be difficult to reproduce. Forcing these errors in a controlled environment +can help the developer find and fix bugs before their code is shipped in a +production system. Injecting an error on the Linux NFS server will allow us to +observe how the client reacts and if it manages to recover its state correctly. + +NFSD_FAULT_INJECTION must be selected when configuring the kernel to use this +feature. + + +Using Fault Injection +===================== +On the client, mount the fault injection server through NFS v4.0+ and do some +work over NFS (open files, take locks, ...). + +On the server, mount the debugfs filesystem to and ls +/nfsd. This will show a list of files that will be used for +injecting faults on the NFS server. As root, write a number n to the file +corresponding to the action you want the server to take. The server will then +process the first n items it finds. So if you want to forget 5 locks, echo '5' +to /nfsd/forget_locks. A value of 0 will tell the server to forget +all corresponding items. A log message will be created containing the number +of items forgotten (check dmesg). + +Go back to work on the client and check if the client recovered from the error +correctly. + + +Available Faults +================ +forget_clients: + The NFS server keeps a list of clients that have placed a mount call. If + this list is cleared, the server will have no knowledge of who the client + is, forcing the client to reauthenticate with the server. + +forget_openowners: + The NFS server keeps a list of what files are currently opened and who + they were opened by. Clearing this list will force the client to reopen + its files. + +forget_locks: + The NFS server keeps a list of what files are currently locked in the VFS. + Clearing this list will force the client to reclaim its locks (files are + unlocked through the VFS as they are cleared from this list). + +forget_delegations: + A delegation is used to assure the client that a file, or part of a file, + has not changed since the delegation was awarded. Clearing this list will + force the client to reaquire its delegation before accessing the file + again. + +recall_delegations: + Delegations can be recalled by the server when another client attempts to + access a file. This test will notify the client that its delegation has + been revoked, forcing the client to reaquire the delegation before using + the file again. + + +tools/nfs/inject_faults.sh script +================================= +This script has been created to ease the fault injection process. This script +will detect the mounted debugfs directory and write to the files located there +based on the arguments passed by the user. For example, running +`inject_faults.sh forget_locks 1` as root will instruct the server to forget +one lock. Running `inject_faults forget_locks` will instruct the server to +forgetall locks. -- cgit v0.10.2 From 72083396074035ffa5cf81b6bb3e55f1d615badf Mon Sep 17 00:00:00 2001 From: Bryan Schumaker Date: Tue, 1 Nov 2011 15:24:59 -0400 Subject: NFSD: Call nfsd4_init_slabs() from init_nfsd() init_nfsd() was calling free_slabs() during cleanup code, but the call to init_slabs() was hidden in nfsd4_state_init(). This could be confusing to people unfamiliar with the code. Signed-off-by: Bryan Schumaker Signed-off-by: J. Bruce Fields diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index a511eff..1d6812d 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -2301,7 +2301,7 @@ nfsd4_free_slabs(void) nfsd4_free_slab(&deleg_slab); } -static int +int nfsd4_init_slabs(void) { openowner_slab = kmem_cache_create("nfsd4_openowners", @@ -4546,14 +4546,11 @@ void nfsd_recall_delegations(u64 num) /* initialization to perform at module load time: */ -int +void nfs4_state_init(void) { - int i, status; + int i; - status = nfsd4_init_slabs(); - if (status) - return status; for (i = 0; i < CLIENT_HASH_SIZE; i++) { INIT_LIST_HEAD(&conf_id_hashtbl[i]); INIT_LIST_HEAD(&conf_str_hashtbl[i]); @@ -4577,7 +4574,6 @@ nfs4_state_init(void) INIT_LIST_HEAD(&client_lru); INIT_LIST_HEAD(&del_recall_lru); reclaim_str_hashtbl_size = 0; - return 0; } static void diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c index b2e8093..8daa935 100644 --- a/fs/nfsd/nfsctl.c +++ b/fs/nfsd/nfsctl.c @@ -1129,9 +1129,10 @@ static int __init init_nfsd(void) int retval; printk(KERN_INFO "Installing knfsd (copyright (C) 1996 okir@monad.swb.de).\n"); - retval = nfs4_state_init(); /* nfs4 locking state */ + retval = nfsd4_init_slabs(); if (retval) return retval; + nfs4_state_init(); retval = nfsd_fault_inject_init(); /* nfsd fault injection controls */ if (retval) goto out_free_slabs; diff --git a/fs/nfsd/nfsd.h b/fs/nfsd/nfsd.h index 58134a2..4e2ee29 100644 --- a/fs/nfsd/nfsd.h +++ b/fs/nfsd/nfsd.h @@ -104,14 +104,16 @@ static inline int nfsd_v4client(struct svc_rqst *rq) */ #ifdef CONFIG_NFSD_V4 extern unsigned int max_delegations; -int nfs4_state_init(void); +void nfs4_state_init(void); +int nfsd4_init_slabs(void); void nfsd4_free_slabs(void); int nfs4_state_start(void); void nfs4_state_shutdown(void); void nfs4_reset_lease(time_t leasetime); int nfs4_reset_recoverydir(char *recdir); #else -static inline int nfs4_state_init(void) { return 0; } +static inline void nfs4_state_init(void) { } +static inline int nfsd4_init_slabs(void) { return 0; } static inline void nfsd4_free_slabs(void) { } static inline int nfs4_state_start(void) { return 0; } static inline void nfs4_state_shutdown(void) { } -- cgit v0.10.2 From c7e8472cf8ae877b232eb506284a5b15cf7efb2c Mon Sep 17 00:00:00 2001 From: Bryan Schumaker Date: Tue, 1 Nov 2011 14:18:28 -0400 Subject: NFSD: Remove unnecessary whitespace The close parenthesis was hard to find with it spaced so far over. Signed-off-by: Bryan Schumaker [bfields@redhat.com: get all these lines under 80 chars while we're here] Signed-off-by: J. Bruce Fields diff --git a/fs/nfsd/nfsd.h b/fs/nfsd/nfsd.h index 4e2ee29..1d1e858 100644 --- a/fs/nfsd/nfsd.h +++ b/fs/nfsd/nfsd.h @@ -340,15 +340,15 @@ static inline u32 nfsd_suppattrs2(u32 minorversion) } /* These will return ERR_INVAL if specified in GETATTR or READDIR. */ -#define NFSD_WRITEONLY_ATTRS_WORD1 \ -(FATTR4_WORD1_TIME_ACCESS_SET | FATTR4_WORD1_TIME_MODIFY_SET) +#define NFSD_WRITEONLY_ATTRS_WORD1 \ + (FATTR4_WORD1_TIME_ACCESS_SET | FATTR4_WORD1_TIME_MODIFY_SET) /* These are the only attrs allowed in CREATE/OPEN/SETATTR. */ -#define NFSD_WRITEABLE_ATTRS_WORD0 \ -(FATTR4_WORD0_SIZE | FATTR4_WORD0_ACL ) -#define NFSD_WRITEABLE_ATTRS_WORD1 \ -(FATTR4_WORD1_MODE | FATTR4_WORD1_OWNER | FATTR4_WORD1_OWNER_GROUP \ - | FATTR4_WORD1_TIME_ACCESS_SET | FATTR4_WORD1_TIME_MODIFY_SET) +#define NFSD_WRITEABLE_ATTRS_WORD0 \ + (FATTR4_WORD0_SIZE | FATTR4_WORD0_ACL) +#define NFSD_WRITEABLE_ATTRS_WORD1 \ + (FATTR4_WORD1_MODE | FATTR4_WORD1_OWNER | FATTR4_WORD1_OWNER_GROUP \ + | FATTR4_WORD1_TIME_ACCESS_SET | FATTR4_WORD1_TIME_MODIFY_SET) #define NFSD_WRITEABLE_ATTRS_WORD2 0 #define NFSD_SUPPATTR_EXCLCREAT_WORD0 \ -- cgit v0.10.2 From 06f1f864d4ae5804e83785308d41f14a08e4b980 Mon Sep 17 00:00:00 2001 From: "J. Bruce Fields" Date: Mon, 7 Nov 2011 16:58:18 -0500 Subject: nfsd4: hash lockowners to simplify RELEASE_LOCKOWNER Hash lockowners on just the owner string rather than on (owner, inode). This makes the owner-string lookup needed for RELEASE_LOCKOWNER simpler (currently it's doing at a linear search through the entire hash table!). That may come at the expense of making (owner, inode) lookups more expensive if a client reuses the same lockowner across multiple files. We might add a separate lookup for that. Signed-off-by: J. Bruce Fields diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 1d6812d..eec9900 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -3746,15 +3746,6 @@ last_byte_offset(u64 start, u64 len) return end > start ? end - 1: NFS4_MAX_UINT64; } -static inline unsigned int -lock_ownerstr_hashval(struct inode *inode, u32 cl_id, - struct xdr_netobj *ownername) -{ - return (file_hashval(inode) + cl_id - + opaque_hashval(ownername->data, ownername->len)) - & LOCK_HASH_MASK; -} - static struct list_head lock_ownerstr_hashtbl[LOCK_HASH_SIZE]; /* @@ -3824,7 +3815,7 @@ static struct nfs4_lockowner * find_lockowner_str(struct inode *inode, clientid_t *clid, struct xdr_netobj *owner) { - unsigned int hashval = lock_ownerstr_hashval(inode, clid->cl_id, owner); + unsigned int hashval = open_ownerstr_hashval(clid->cl_id, owner); struct nfs4_lockowner *lo; struct nfs4_stateowner *op; @@ -3847,7 +3838,7 @@ static void hash_lockowner(struct nfs4_lockowner *lo, unsigned int strhashval, s * Called in nfsd4_lock - therefore, OPEN and OPEN_CONFIRM (if needed) has * occurred. * - * strhashval = lock_ownerstr_hashval + * strhashval = open_ownerstr_hashval */ static struct nfs4_lockowner * @@ -3922,7 +3913,7 @@ __be32 lookup_or_create_lock_state(struct nfsd4_compound_state *cstate, struct n struct nfs4_ol_stateid, st_perstateowner); return nfs_ok; } - strhashval = lock_ownerstr_hashval(fi->fi_inode, cl->cl_clientid.cl_id, + strhashval = open_ownerstr_hashval(cl->cl_clientid.cl_id, &lock->v.new.owner); lo = alloc_init_lock_stateowner(strhashval, cl, ost, lock); if (lo == NULL) @@ -4286,7 +4277,7 @@ nfsd4_release_lockowner(struct svc_rqst *rqstp, struct nfs4_ol_stateid *stp; struct xdr_netobj *owner = &rlockowner->rl_owner; struct list_head matches; - int i; + unsigned int hashval = open_ownerstr_hashval(clid->cl_id, owner); __be32 status; dprintk("nfsd4_release_lockowner clientid: (%08x/%08x):\n", @@ -4301,22 +4292,17 @@ nfsd4_release_lockowner(struct svc_rqst *rqstp, nfs4_lock_state(); status = nfserr_locks_held; - /* XXX: we're doing a linear search through all the lockowners. - * Yipes! For now we'll just hope clients aren't really using - * release_lockowner much, but eventually we have to fix these - * data structures. */ INIT_LIST_HEAD(&matches); - for (i = 0; i < LOCK_HASH_SIZE; i++) { - list_for_each_entry(sop, &lock_ownerstr_hashtbl[i], so_strhash) { - if (!same_owner_str(sop, owner, clid)) - continue; - list_for_each_entry(stp, &sop->so_stateids, - st_perstateowner) { - lo = lockowner(sop); - if (check_for_locks(stp->st_file, lo)) - goto out; - list_add(&lo->lo_list, &matches); - } + + list_for_each_entry(sop, &lock_ownerstr_hashtbl[hashval], so_strhash) { + if (!same_owner_str(sop, owner, clid)) + continue; + list_for_each_entry(stp, &sop->so_stateids, + st_perstateowner) { + lo = lockowner(sop); + if (check_for_locks(stp->st_file, lo)) + goto out; + list_add(&lo->lo_list, &matches); } } /* Clients probably won't expect us to return with some (but not all) -- cgit v0.10.2 From f7901f9b4ae06d65537ff3db8605e657f6d4afce Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Thu, 3 Nov 2011 08:39:12 -0300 Subject: [media] mxl111sf: add mxl111sf_tuner_get_if_frequency Reported-by: Antti Palosaari Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/dvb/dvb-usb/mxl111sf-tuner.c b/drivers/media/dvb/dvb-usb/mxl111sf-tuner.c index a634105..3bfc6d8 100644 --- a/drivers/media/dvb/dvb-usb/mxl111sf-tuner.c +++ b/drivers/media/dvb/dvb-usb/mxl111sf-tuner.c @@ -38,6 +38,8 @@ struct mxl111sf_tuner_state { struct mxl111sf_tuner_config *cfg; + enum mxl_if_freq if_freq; + u32 frequency; u32 bandwidth; }; @@ -186,7 +188,10 @@ static int mxl1x1sf_tuner_set_if_output_freq(struct mxl111sf_tuner_state *state) ctrl = iffcw & 0x00ff; #endif ret = mxl111sf_tuner_write_reg(state, V6_TUNER_IF_FCW_REG, ctrl); - mxl_fail(ret); + if (mxl_fail(ret)) + goto fail; + + state->if_freq = state->cfg->if_freq; fail: return ret; } @@ -407,6 +412,54 @@ static int mxl111sf_tuner_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth) return 0; } +static int mxl111sf_tuner_get_if_frequency(struct dvb_frontend *fe, + u32 *frequency) +{ + struct mxl111sf_tuner_state *state = fe->tuner_priv; + + *frequency = 0; + + switch (state->if_freq) { + case MXL_IF_4_0: /* 4.0 MHz */ + *frequency = 4000000; + break; + case MXL_IF_4_5: /* 4.5 MHz */ + *frequency = 4500000; + break; + case MXL_IF_4_57: /* 4.57 MHz */ + *frequency = 4570000; + break; + case MXL_IF_5_0: /* 5.0 MHz */ + *frequency = 5000000; + break; + case MXL_IF_5_38: /* 5.38 MHz */ + *frequency = 5380000; + break; + case MXL_IF_6_0: /* 6.0 MHz */ + *frequency = 6000000; + break; + case MXL_IF_6_28: /* 6.28 MHz */ + *frequency = 6280000; + break; + case MXL_IF_7_2: /* 7.2 MHz */ + *frequency = 7200000; + break; + case MXL_IF_35_25: /* 35.25 MHz */ + *frequency = 35250000; + break; + case MXL_IF_36: /* 36 MHz */ + *frequency = 36000000; + break; + case MXL_IF_36_15: /* 36.15 MHz */ + *frequency = 36150000; + break; + case MXL_IF_44: /* 44 MHz */ + *frequency = 44000000; + break; + } + return 0; +} + static int mxl111sf_tuner_release(struct dvb_frontend *fe) { struct mxl111sf_tuner_state *state = fe->tuner_priv; @@ -436,6 +489,7 @@ static struct dvb_tuner_ops mxl111sf_tuner_tuner_ops = { .get_rf_strength = mxl111sf_get_rf_strength, .get_frequency = mxl111sf_tuner_get_frequency, .get_bandwidth = mxl111sf_tuner_get_bandwidth, + .get_if_frequency = mxl111sf_tuner_get_if_frequency, .release = mxl111sf_tuner_release, }; -- cgit v0.10.2 From d697b4ce9490d82380a3fe153a7f9fbe017295f2 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Thu, 3 Nov 2011 09:12:04 -0300 Subject: [media] mxl5007t: add mxl5007t_get_if_frequency Reported-by: Antti Palosaari Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/common/tuners/mxl5007t.c b/drivers/media/common/tuners/mxl5007t.c index 7eb1bf7..2f0e550 100644 --- a/drivers/media/common/tuners/mxl5007t.c +++ b/drivers/media/common/tuners/mxl5007t.c @@ -165,6 +165,8 @@ struct mxl5007t_state { struct reg_pair_t tab_init_cable[ARRAY_SIZE(init_tab_cable)]; struct reg_pair_t tab_rftune[ARRAY_SIZE(reg_pair_rftune)]; + enum mxl5007t_if_freq if_freq; + u32 frequency; u32 bandwidth; }; @@ -286,6 +288,8 @@ static void mxl5007t_set_if_freq_bits(struct mxl5007t_state *state, /* set inverted IF or normal IF */ set_reg_bits(state->tab_init, 0x02, 0x10, invert_if ? 0x10 : 0x00); + state->if_freq = if_freq; + return; } @@ -737,6 +741,50 @@ static int mxl5007t_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth) return 0; } +static int mxl5007t_get_if_frequency(struct dvb_frontend *fe, u32 *frequency) +{ + struct mxl5007t_state *state = fe->tuner_priv; + + *frequency = 0; + + switch (state->if_freq) { + case MxL_IF_4_MHZ: + *frequency = 4000000; + break; + case MxL_IF_4_5_MHZ: + *frequency = 4500000; + break; + case MxL_IF_4_57_MHZ: + *frequency = 4570000; + break; + case MxL_IF_5_MHZ: + *frequency = 5000000; + break; + case MxL_IF_5_38_MHZ: + *frequency = 5380000; + break; + case MxL_IF_6_MHZ: + *frequency = 6000000; + break; + case MxL_IF_6_28_MHZ: + *frequency = 6280000; + break; + case MxL_IF_9_1915_MHZ: + *frequency = 9191500; + break; + case MxL_IF_35_25_MHZ: + *frequency = 35250000; + break; + case MxL_IF_36_15_MHZ: + *frequency = 36150000; + break; + case MxL_IF_44_MHZ: + *frequency = 44000000; + break; + } + return 0; +} + static int mxl5007t_release(struct dvb_frontend *fe) { struct mxl5007t_state *state = fe->tuner_priv; @@ -766,6 +814,7 @@ static struct dvb_tuner_ops mxl5007t_tuner_ops = { .get_frequency = mxl5007t_get_frequency, .get_bandwidth = mxl5007t_get_bandwidth, .release = mxl5007t_release, + .get_if_frequency = mxl5007t_get_if_frequency, }; static int mxl5007t_get_chip_id(struct mxl5007t_state *state) -- cgit v0.10.2 From 8c8ee11345fa26e46cbc9ec88581736e38915b16 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Thu, 3 Nov 2011 09:59:42 -0300 Subject: [media] tda18271: add tda18271_get_if_frequency Reported-by: Antti Palosaari Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/common/tuners/tda18271-fe.c b/drivers/media/common/tuners/tda18271-fe.c index 63cc400..3347c5b 100644 --- a/drivers/media/common/tuners/tda18271-fe.c +++ b/drivers/media/common/tuners/tda18271-fe.c @@ -994,6 +994,7 @@ static int tda18271_set_params(struct dvb_frontend *fe, if (tda_fail(ret)) goto fail; + priv->if_freq = map->if_freq; priv->frequency = freq; priv->bandwidth = (fe->ops.info.type == FE_OFDM) ? params->u.ofdm.bandwidth : 0; @@ -1050,6 +1051,7 @@ static int tda18271_set_analog_params(struct dvb_frontend *fe, if (tda_fail(ret)) goto fail; + priv->if_freq = map->if_freq; priv->frequency = freq; priv->bandwidth = 0; fail: @@ -1086,6 +1088,13 @@ static int tda18271_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth) return 0; } +static int tda18271_get_if_frequency(struct dvb_frontend *fe, u32 *frequency) +{ + struct tda18271_priv *priv = fe->tuner_priv; + *frequency = (u32)priv->if_freq * 1000; + return 0; +} + /* ------------------------------------------------------------------ */ #define tda18271_update_std(std_cfg, name) do { \ @@ -1245,6 +1254,7 @@ static const struct dvb_tuner_ops tda18271_tuner_ops = { .set_config = tda18271_set_config, .get_frequency = tda18271_get_frequency, .get_bandwidth = tda18271_get_bandwidth, + .get_if_frequency = tda18271_get_if_frequency, }; struct dvb_frontend *tda18271_attach(struct dvb_frontend *fe, u8 addr, diff --git a/drivers/media/common/tuners/tda18271-priv.h b/drivers/media/common/tuners/tda18271-priv.h index 94340f4..454c152 100644 --- a/drivers/media/common/tuners/tda18271-priv.h +++ b/drivers/media/common/tuners/tda18271-priv.h @@ -122,6 +122,8 @@ struct tda18271_priv { struct mutex lock; + u16 if_freq; + u32 frequency; u32 bandwidth; }; -- cgit v0.10.2 From 918847341af0f5f1907fc0b52549f0dc29192c03 Mon Sep 17 00:00:00 2001 From: Kamil Debski Date: Thu, 6 Oct 2011 11:32:12 -0300 Subject: [media] v4l: add G2D driver for s5p device family G2D is a 2D graphics accelerator engine present in the s5p family of Samsung SoCs. It is capable of bitblt and raster operations on images having dimensions of up to 8000x8000. Signed-off-by: Kamil Debski Signed-off-by: Kyungmin Park Signed-off-by: Marek Szyprowski Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig index b303a3f..d960656 100644 --- a/drivers/media/video/Kconfig +++ b/drivers/media/video/Kconfig @@ -1098,6 +1098,15 @@ config VIDEO_MEM2MEM_TESTDEV This is a virtual test device for the memory-to-memory driver framework. +config VIDEO_SAMSUNG_S5P_G2D + tristate "Samsung S5P and EXYNOS4 G2D 2d graphics accelerator driver" + depends on VIDEO_DEV && VIDEO_V4L2 && PLAT_S5P + select VIDEOBUF2_DMA_CONTIG + select V4L2_MEM2MEM_DEV + default n + ---help--- + This is a v4l2 driver for Samsung S5P and EXYNOS4 G2D + 2d graphics accelerator. config VIDEO_SAMSUNG_S5P_MFC tristate "Samsung S5P MFC 5.1 Video Codec" diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile index 117f9c4..ddeaa6c 100644 --- a/drivers/media/video/Makefile +++ b/drivers/media/video/Makefile @@ -180,6 +180,8 @@ obj-$(CONFIG_VIDEO_SAMSUNG_S5P_FIMC) += s5p-fimc/ obj-$(CONFIG_VIDEO_SAMSUNG_S5P_MFC) += s5p-mfc/ obj-$(CONFIG_VIDEO_SAMSUNG_S5P_TV) += s5p-tv/ +obj-$(CONFIG_VIDEO_SAMSUNG_S5P_G2D) += s5p-g2d/ + obj-$(CONFIG_ARCH_DAVINCI) += davinci/ obj-$(CONFIG_VIDEO_SH_VOU) += sh_vou.o diff --git a/drivers/media/video/s5p-g2d/Makefile b/drivers/media/video/s5p-g2d/Makefile new file mode 100644 index 0000000..2c48c41 --- /dev/null +++ b/drivers/media/video/s5p-g2d/Makefile @@ -0,0 +1,3 @@ +s5p-g2d-objs := g2d.o g2d-hw.o + +obj-$(CONFIG_VIDEO_SAMSUNG_S5P_G2D) += s5p-g2d.o diff --git a/drivers/media/video/s5p-g2d/g2d-hw.c b/drivers/media/video/s5p-g2d/g2d-hw.c new file mode 100644 index 0000000..e5249f3 --- /dev/null +++ b/drivers/media/video/s5p-g2d/g2d-hw.c @@ -0,0 +1,106 @@ +/* + * Samsung S5P G2D - 2D Graphics Accelerator Driver + * + * Copyright (c) 2011 Samsung Electronics Co., Ltd. + * Kamil Debski, + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the + * License, or (at your option) any later version + */ + +#include + +#include "g2d.h" +#include "g2d-regs.h" + +#define w(x, a) writel((x), d->regs + (a)) +#define r(a) readl(d->regs + (a)) + +/* g2d_reset clears all g2d registers */ +void g2d_reset(struct g2d_dev *d) +{ + w(1, SOFT_RESET_REG); +} + +void g2d_set_src_size(struct g2d_dev *d, struct g2d_frame *f) +{ + u32 n; + u32 stride; + + w(f->stride & 0xFFFF, SRC_STRIDE_REG); + + n = f->o_height & 0xFFF; + n <<= 16; + n |= f->o_width & 0xFFF; + w(n, SRC_LEFT_TOP_REG); + + n = f->bottom & 0xFFF; + n <<= 16; + n |= f->right & 0xFFF; + w(n, SRC_RIGHT_BOTTOM_REG); + + w(f->fmt->hw, SRC_COLOR_MODE_REG); +} + +void g2d_set_src_addr(struct g2d_dev *d, dma_addr_t a) +{ + w(a, SRC_BASE_ADDR_REG); +} + +void g2d_set_dst_size(struct g2d_dev *d, struct g2d_frame *f) +{ + u32 n; + u32 stride; + + w(f->stride & 0xFFFF, DST_STRIDE_REG); + + n = f->o_height & 0xFFF; + n <<= 16; + n |= f->o_width & 0xFFF; + w(n, DST_LEFT_TOP_REG); + + n = f->bottom & 0xFFF; + n <<= 16; + n |= f->right & 0xFFF; + w(n, DST_RIGHT_BOTTOM_REG); + + w(f->fmt->hw, DST_COLOR_MODE_REG); +} + +void g2d_set_dst_addr(struct g2d_dev *d, dma_addr_t a) +{ + w(a, DST_BASE_ADDR_REG); +} + +void g2d_set_rop4(struct g2d_dev *d, u32 r) +{ + w(r, ROP4_REG); +} + +u32 g2d_cmd_stretch(u32 e) +{ + e &= 1; + return e << 4; +} + +void g2d_set_cmd(struct g2d_dev *d, u32 c) +{ + w(c, BITBLT_COMMAND_REG); +} + +void g2d_start(struct g2d_dev *d) +{ + /* Clear cache */ + w(0x7, CACHECTL_REG); + /* Enable interrupt */ + w(1, INTEN_REG); + /* Start G2D engine */ + w(1, BITBLT_START_REG); +} + +void g2d_clear_int(struct g2d_dev *d) +{ + w(1, INTC_PEND_REG); +} diff --git a/drivers/media/video/s5p-g2d/g2d-regs.h b/drivers/media/video/s5p-g2d/g2d-regs.h new file mode 100644 index 0000000..02e1cf5 --- /dev/null +++ b/drivers/media/video/s5p-g2d/g2d-regs.h @@ -0,0 +1,115 @@ +/* + * Samsung S5P G2D - 2D Graphics Accelerator Driver + * + * Copyright (c) 2011 Samsung Electronics Co., Ltd. + * Kamil Debski, + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the + * License, or (at your option) any later version + */ + +/* General Registers */ +#define SOFT_RESET_REG 0x0000 /* Software reset reg */ +#define INTEN_REG 0x0004 /* Interrupt Enable reg */ +#define INTC_PEND_REG 0x000C /* Interrupt Control Pending reg */ +#define FIFO_STAT_REG 0x0010 /* Command FIFO Status reg */ +#define AXI_ID_MODE_REG 0x0014 /* AXI Read ID Mode reg */ +#define CACHECTL_REG 0x0018 /* Cache & Buffer clear reg */ +#define AXI_MODE_REG 0x001C /* AXI Mode reg */ + +/* Command Registers */ +#define BITBLT_START_REG 0x0100 /* BitBLT Start reg */ +#define BITBLT_COMMAND_REG 0x0104 /* Command reg for BitBLT */ + +/* Parameter Setting Registers (Rotate & Direction) */ +#define ROTATE_REG 0x0200 /* Rotation reg */ +#define SRC_MSK_DIRECT_REG 0x0204 /* Src and Mask Direction reg */ +#define DST_PAT_DIRECT_REG 0x0208 /* Dest and Pattern Direction reg */ + +/* Parameter Setting Registers (Src) */ +#define SRC_SELECT_REG 0x0300 /* Src Image Selection reg */ +#define SRC_BASE_ADDR_REG 0x0304 /* Src Image Base Address reg */ +#define SRC_STRIDE_REG 0x0308 /* Src Stride reg */ +#define SRC_COLOR_MODE_REG 0x030C /* Src Image Color Mode reg */ +#define SRC_LEFT_TOP_REG 0x0310 /* Src Left Top Coordinate reg */ +#define SRC_RIGHT_BOTTOM_REG 0x0314 /* Src Right Bottom Coordinate reg */ + +/* Parameter Setting Registers (Dest) */ +#define DST_SELECT_REG 0x0400 /* Dest Image Selection reg */ +#define DST_BASE_ADDR_REG 0x0404 /* Dest Image Base Address reg */ +#define DST_STRIDE_REG 0x0408 /* Dest Stride reg */ +#define DST_COLOR_MODE_REG 0x040C /* Dest Image Color Mode reg */ +#define DST_LEFT_TOP_REG 0x0410 /* Dest Left Top Coordinate reg */ +#define DST_RIGHT_BOTTOM_REG 0x0414 /* Dest Right Bottom Coordinate reg */ + +/* Parameter Setting Registers (Pattern) */ +#define PAT_BASE_ADDR_REG 0x0500 /* Pattern Image Base Address reg */ +#define PAT_SIZE_REG 0x0504 /* Pattern Image Size reg */ +#define PAT_COLOR_MODE_REG 0x0508 /* Pattern Image Color Mode reg */ +#define PAT_OFFSET_REG 0x050C /* Pattern Left Top Coordinate reg */ +#define PAT_STRIDE_REG 0x0510 /* Pattern Stride reg */ + +/* Parameter Setting Registers (Mask) */ +#define MASK_BASE_ADDR_REG 0x0520 /* Mask Base Address reg */ +#define MASK_STRIDE_REG 0x0524 /* Mask Stride reg */ + +/* Parameter Setting Registers (Clipping Window) */ +#define CW_LT_REG 0x0600 /* LeftTop coordinates of Clip Window */ +#define CW_RB_REG 0x0604 /* RightBottom coordinates of Clip + Window */ + +/* Parameter Setting Registers (ROP & Alpha Setting) */ +#define THIRD_OPERAND_REG 0x0610 /* Third Operand Selection reg */ +#define ROP4_REG 0x0614 /* Raster Operation reg */ +#define ALPHA_REG 0x0618 /* Alpha value, Fading offset value */ + +/* Parameter Setting Registers (Color) */ +#define FG_COLOR_REG 0x0700 /* Foreground Color reg */ +#define BG_COLOR_REG 0x0704 /* Background Color reg */ +#define BS_COLOR_REG 0x0708 /* Blue Screen Color reg */ + +/* Parameter Setting Registers (Color Key) */ +#define SRC_COLORKEY_CTRL_REG 0x0710 /* Src Colorkey control reg */ +#define SRC_COLORKEY_DR_MIN_REG 0x0714 /* Src Colorkey Decision Reference + Min reg */ +#define SRC_COLORKEY_DR_MAX_REG 0x0718 /* Src Colorkey Decision Reference + Max reg */ +#define DST_COLORKEY_CTRL_REG 0x071C /* Dest Colorkey control reg */ +#define DST_COLORKEY_DR_MIN_REG 0x0720 /* Dest Colorkey Decision Reference + Min reg */ +#define DST_COLORKEY_DR_MAX_REG 0x0724 /* Dest Colorkey Decision Reference + Max reg */ + +/* Color mode values */ + +#define ORDER_XRGB 0 +#define ORDER_RGBX 1 +#define ORDER_XBGR 2 +#define ORDER_BGRX 3 + +#define MODE_XRGB_8888 0 +#define MODE_ARGB_8888 1 +#define MODE_RGB_565 2 +#define MODE_XRGB_1555 3 +#define MODE_ARGB_1555 4 +#define MODE_XRGB_4444 5 +#define MODE_ARGB_4444 6 +#define MODE_PACKED_RGB_888 7 + +#define COLOR_MODE(o, m) (((o) << 4) | (m)) + +/* ROP4 operation values */ +#define ROP4_COPY 0xCCCC +#define ROP4_INVERT 0x3333 + +/* Hardware limits */ +#define MAX_WIDTH 8000 +#define MAX_HEIGHT 8000 + +#define G2D_TIMEOUT 500 + +#define DEFAULT_WIDTH 100 +#define DEFAULT_HEIGHT 100 + diff --git a/drivers/media/video/s5p-g2d/g2d.c b/drivers/media/video/s5p-g2d/g2d.c new file mode 100644 index 0000000..1f156c8 --- /dev/null +++ b/drivers/media/video/s5p-g2d/g2d.c @@ -0,0 +1,824 @@ +/* + * Samsung S5P G2D - 2D Graphics Accelerator Driver + * + * Copyright (c) 2011 Samsung Electronics Co., Ltd. + * Kamil Debski, + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the + * License, or (at your option) any later version + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "g2d.h" +#include "g2d-regs.h" + +#define fh2ctx(__fh) container_of(__fh, struct g2d_ctx, fh) + +static struct g2d_fmt formats[] = { + { + .name = "XRGB_8888", + .fourcc = V4L2_PIX_FMT_RGB32, + .depth = 32, + .hw = COLOR_MODE(ORDER_XRGB, MODE_XRGB_8888), + }, + { + .name = "RGB_565", + .fourcc = V4L2_PIX_FMT_RGB565X, + .depth = 16, + .hw = COLOR_MODE(ORDER_XRGB, MODE_RGB_565), + }, + { + .name = "XRGB_1555", + .fourcc = V4L2_PIX_FMT_RGB555X, + .depth = 16, + .hw = COLOR_MODE(ORDER_XRGB, MODE_XRGB_1555), + }, + { + .name = "XRGB_4444", + .fourcc = V4L2_PIX_FMT_RGB444, + .depth = 16, + .hw = COLOR_MODE(ORDER_XRGB, MODE_XRGB_4444), + }, + { + .name = "PACKED_RGB_888", + .fourcc = V4L2_PIX_FMT_RGB24, + .depth = 24, + .hw = COLOR_MODE(ORDER_XRGB, MODE_PACKED_RGB_888), + }, +}; +#define NUM_FORMATS ARRAY_SIZE(formats) + +struct g2d_frame def_frame = { + .width = DEFAULT_WIDTH, + .height = DEFAULT_HEIGHT, + .c_width = DEFAULT_WIDTH, + .c_height = DEFAULT_HEIGHT, + .o_width = 0, + .o_height = 0, + .fmt = &formats[0], + .right = DEFAULT_WIDTH, + .bottom = DEFAULT_HEIGHT, +}; + +struct g2d_fmt *find_fmt(struct v4l2_format *f) +{ + unsigned int i; + for (i = 0; i < NUM_FORMATS; i++) { + if (formats[i].fourcc == f->fmt.pix.pixelformat) + return &formats[i]; + } + return NULL; +} + + +static struct g2d_frame *get_frame(struct g2d_ctx *ctx, + enum v4l2_buf_type type) +{ + switch (type) { + case V4L2_BUF_TYPE_VIDEO_OUTPUT: + return &ctx->in; + case V4L2_BUF_TYPE_VIDEO_CAPTURE: + return &ctx->out; + default: + return ERR_PTR(-EINVAL); + } +} + +static int g2d_queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt, + unsigned int *nbuffers, unsigned int *nplanes, + unsigned int sizes[], void *alloc_ctxs[]) +{ + struct g2d_ctx *ctx = vb2_get_drv_priv(vq); + struct g2d_frame *f = get_frame(ctx, vq->type); + + if (IS_ERR(f)) + return PTR_ERR(f); + + sizes[0] = f->size; + *nplanes = 1; + alloc_ctxs[0] = ctx->dev->alloc_ctx; + + if (*nbuffers == 0) + *nbuffers = 1; + + return 0; +} + +static int g2d_buf_prepare(struct vb2_buffer *vb) +{ + struct g2d_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); + struct g2d_frame *f = get_frame(ctx, vb->vb2_queue->type); + + if (IS_ERR(f)) + return PTR_ERR(f); + vb2_set_plane_payload(vb, 0, f->size); + return 0; +} + +static void g2d_buf_queue(struct vb2_buffer *vb) +{ + struct g2d_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); + v4l2_m2m_buf_queue(ctx->m2m_ctx, vb); +} + + +static struct vb2_ops g2d_qops = { + .queue_setup = g2d_queue_setup, + .buf_prepare = g2d_buf_prepare, + .buf_queue = g2d_buf_queue, +}; + +static int queue_init(void *priv, struct vb2_queue *src_vq, + struct vb2_queue *dst_vq) +{ + struct g2d_ctx *ctx = priv; + int ret; + + memset(src_vq, 0, sizeof(*src_vq)); + src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT; + src_vq->io_modes = VB2_MMAP | VB2_USERPTR; + src_vq->drv_priv = ctx; + src_vq->ops = &g2d_qops; + src_vq->mem_ops = &vb2_dma_contig_memops; + src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer); + + ret = vb2_queue_init(src_vq); + if (ret) + return ret; + + memset(dst_vq, 0, sizeof(*dst_vq)); + dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + dst_vq->io_modes = VB2_MMAP | VB2_USERPTR; + dst_vq->drv_priv = ctx; + dst_vq->ops = &g2d_qops; + dst_vq->mem_ops = &vb2_dma_contig_memops; + dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer); + + return vb2_queue_init(dst_vq); +} + +static int g2d_s_ctrl(struct v4l2_ctrl *ctrl) +{ + struct g2d_ctx *ctx = container_of(ctrl->handler, struct g2d_ctx, + ctrl_handler); + switch (ctrl->id) { + case V4L2_CID_COLORFX: + if (ctrl->val == V4L2_COLORFX_NEGATIVE) + ctx->rop = ROP4_INVERT; + else + ctx->rop = ROP4_COPY; + default: + v4l2_err(&ctx->dev->v4l2_dev, "unknown control\n"); + return -EINVAL; + } + return 0; +} + +static const struct v4l2_ctrl_ops g2d_ctrl_ops = { + .s_ctrl = g2d_s_ctrl, +}; + +int g2d_setup_ctrls(struct g2d_ctx *ctx) +{ + struct g2d_dev *dev = ctx->dev; + + v4l2_ctrl_handler_init(&ctx->ctrl_handler, 1); + if (ctx->ctrl_handler.error) { + v4l2_err(&dev->v4l2_dev, "v4l2_ctrl_handler_init failed\n"); + return ctx->ctrl_handler.error; + } + + v4l2_ctrl_new_std_menu( + &ctx->ctrl_handler, + &g2d_ctrl_ops, + V4L2_CID_COLORFX, + V4L2_COLORFX_NEGATIVE, + ~((1 << V4L2_COLORFX_NONE) | (1 << V4L2_COLORFX_NEGATIVE)), + V4L2_COLORFX_NONE); + + if (ctx->ctrl_handler.error) { + v4l2_err(&dev->v4l2_dev, "v4l2_ctrl_handler_init failed\n"); + return ctx->ctrl_handler.error; + } + + return 0; +} + +static int g2d_open(struct file *file) +{ + struct g2d_dev *dev = video_drvdata(file); + struct g2d_ctx *ctx = NULL; + int ret = 0; + + ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + if (!ctx) + return -ENOMEM; + ctx->dev = dev; + /* Set default formats */ + ctx->in = def_frame; + ctx->out = def_frame; + + ctx->m2m_ctx = v4l2_m2m_ctx_init(dev->m2m_dev, ctx, &queue_init); + if (IS_ERR(ctx->m2m_ctx)) { + ret = PTR_ERR(ctx->m2m_ctx); + kfree(ctx); + return ret; + } + v4l2_fh_init(&ctx->fh, video_devdata(file)); + file->private_data = &ctx->fh; + v4l2_fh_add(&ctx->fh); + + g2d_setup_ctrls(ctx); + + /* Write the default values to the ctx struct */ + v4l2_ctrl_handler_setup(&ctx->ctrl_handler); + + ctx->fh.ctrl_handler = &ctx->ctrl_handler; + + v4l2_info(&dev->v4l2_dev, "instance opened\n"); + return 0; +} + +static int g2d_release(struct file *file) +{ + struct g2d_dev *dev = video_drvdata(file); + struct g2d_ctx *ctx = fh2ctx(file->private_data); + + v4l2_ctrl_handler_free(&ctx->ctrl_handler); + v4l2_fh_del(&ctx->fh); + v4l2_fh_exit(&ctx->fh); + kfree(ctx); + v4l2_info(&dev->v4l2_dev, "instance closed\n"); + return 0; +} + + +static int vidioc_querycap(struct file *file, void *priv, + struct v4l2_capability *cap) +{ + strncpy(cap->driver, G2D_NAME, sizeof(cap->driver) - 1); + strncpy(cap->card, G2D_NAME, sizeof(cap->card) - 1); + cap->bus_info[0] = 0; + cap->version = KERNEL_VERSION(1, 0, 0); + cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_OUTPUT + | V4L2_CAP_STREAMING; + return 0; +} + +static int vidioc_enum_fmt(struct file *file, void *prv, struct v4l2_fmtdesc *f) +{ + struct g2d_fmt *fmt; + if (f->index >= NUM_FORMATS) + return -EINVAL; + fmt = &formats[f->index]; + f->pixelformat = fmt->fourcc; + strncpy(f->description, fmt->name, sizeof(f->description) - 1); + return 0; +} + +static int vidioc_g_fmt(struct file *file, void *prv, struct v4l2_format *f) +{ + struct g2d_ctx *ctx = prv; + struct vb2_queue *vq; + struct g2d_frame *frm; + + vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type); + if (!vq) + return -EINVAL; + frm = get_frame(ctx, f->type); + if (IS_ERR(frm)) + return PTR_ERR(frm); + + f->fmt.pix.width = frm->width; + f->fmt.pix.height = frm->height; + f->fmt.pix.field = V4L2_FIELD_NONE; + f->fmt.pix.pixelformat = frm->fmt->fourcc; + f->fmt.pix.bytesperline = (frm->width * frm->fmt->depth) >> 3; + f->fmt.pix.sizeimage = frm->size; + return 0; +} + +static int vidioc_try_fmt(struct file *file, void *prv, struct v4l2_format *f) +{ + struct g2d_fmt *fmt; + enum v4l2_field *field; + + fmt = find_fmt(f); + if (!fmt) + return -EINVAL; + + field = &f->fmt.pix.field; + if (*field == V4L2_FIELD_ANY) + *field = V4L2_FIELD_NONE; + else if (*field != V4L2_FIELD_NONE) + return -EINVAL; + + if (f->fmt.pix.width > MAX_WIDTH) + f->fmt.pix.width = MAX_WIDTH; + if (f->fmt.pix.height > MAX_HEIGHT) + f->fmt.pix.height = MAX_HEIGHT; + + if (f->fmt.pix.width < 1) + f->fmt.pix.width = 1; + if (f->fmt.pix.height < 1) + f->fmt.pix.height = 1; + + f->fmt.pix.bytesperline = (f->fmt.pix.width * fmt->depth) >> 3; + f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline; + return 0; +} + +static int vidioc_s_fmt(struct file *file, void *prv, struct v4l2_format *f) +{ + struct g2d_ctx *ctx = prv; + struct g2d_dev *dev = ctx->dev; + struct vb2_queue *vq; + struct g2d_frame *frm; + struct g2d_fmt *fmt; + int ret = 0; + + /* Adjust all values accordingly to the hardware capabilities + * and chosen format. */ + ret = vidioc_try_fmt(file, prv, f); + if (ret) + return ret; + vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type); + if (vb2_is_busy(vq)) { + v4l2_err(&dev->v4l2_dev, "queue (%d) bust\n", f->type); + return -EBUSY; + } + frm = get_frame(ctx, f->type); + if (IS_ERR(frm)) + return PTR_ERR(frm); + fmt = find_fmt(f); + if (!fmt) + return -EINVAL; + frm->width = f->fmt.pix.width; + frm->height = f->fmt.pix.height; + frm->size = f->fmt.pix.sizeimage; + /* Reset crop settings */ + frm->o_width = 0; + frm->o_height = 0; + frm->c_width = frm->width; + frm->c_height = frm->height; + frm->right = frm->width; + frm->bottom = frm->height; + frm->fmt = fmt; + frm->stride = f->fmt.pix.bytesperline; + return 0; +} + +static unsigned int g2d_poll(struct file *file, struct poll_table_struct *wait) +{ + struct g2d_ctx *ctx = fh2ctx(file->private_data); + return v4l2_m2m_poll(file, ctx->m2m_ctx, wait); +} + +static int g2d_mmap(struct file *file, struct vm_area_struct *vma) +{ + struct g2d_ctx *ctx = fh2ctx(file->private_data); + return v4l2_m2m_mmap(file, ctx->m2m_ctx, vma); +} + +static int vidioc_reqbufs(struct file *file, void *priv, + struct v4l2_requestbuffers *reqbufs) +{ + struct g2d_ctx *ctx = priv; + return v4l2_m2m_reqbufs(file, ctx->m2m_ctx, reqbufs); +} + +static int vidioc_querybuf(struct file *file, void *priv, + struct v4l2_buffer *buf) +{ + struct g2d_ctx *ctx = priv; + return v4l2_m2m_querybuf(file, ctx->m2m_ctx, buf); +} + +static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf) +{ + struct g2d_ctx *ctx = priv; + return v4l2_m2m_qbuf(file, ctx->m2m_ctx, buf); +} + +static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *buf) +{ + struct g2d_ctx *ctx = priv; + return v4l2_m2m_dqbuf(file, ctx->m2m_ctx, buf); +} + + +static int vidioc_streamon(struct file *file, void *priv, + enum v4l2_buf_type type) +{ + struct g2d_ctx *ctx = priv; + return v4l2_m2m_streamon(file, ctx->m2m_ctx, type); +} + +static int vidioc_streamoff(struct file *file, void *priv, + enum v4l2_buf_type type) +{ + struct g2d_ctx *ctx = priv; + return v4l2_m2m_streamoff(file, ctx->m2m_ctx, type); +} + +static int vidioc_cropcap(struct file *file, void *priv, + struct v4l2_cropcap *cr) +{ + struct g2d_ctx *ctx = priv; + struct g2d_frame *f; + + f = get_frame(ctx, cr->type); + if (IS_ERR(f)) + return PTR_ERR(f); + + cr->bounds.left = 0; + cr->bounds.top = 0; + cr->bounds.width = f->width; + cr->bounds.height = f->height; + cr->defrect = cr->bounds; + return 0; +} + +static int vidioc_g_crop(struct file *file, void *prv, struct v4l2_crop *cr) +{ + struct g2d_ctx *ctx = prv; + struct g2d_frame *f; + + f = get_frame(ctx, cr->type); + if (IS_ERR(f)) + return PTR_ERR(f); + + cr->c.left = f->o_height; + cr->c.top = f->o_width; + cr->c.width = f->c_width; + cr->c.height = f->c_height; + return 0; +} + +static int vidioc_try_crop(struct file *file, void *prv, struct v4l2_crop *cr) +{ + struct g2d_ctx *ctx = prv; + struct g2d_dev *dev = ctx->dev; + struct g2d_frame *f; + + f = get_frame(ctx, cr->type); + if (IS_ERR(f)) + return PTR_ERR(f); + + if (cr->c.top < 0 || cr->c.left < 0) { + v4l2_err(&dev->v4l2_dev, + "doesn't support negative values for top & left\n"); + return -EINVAL; + } + + return 0; +} + +static int vidioc_s_crop(struct file *file, void *prv, struct v4l2_crop *cr) +{ + struct g2d_ctx *ctx = prv; + struct g2d_frame *f; + int ret; + + ret = vidioc_try_crop(file, prv, cr); + if (ret) + return ret; + f = get_frame(ctx, cr->type); + if (IS_ERR(f)) + return PTR_ERR(f); + + f->c_width = cr->c.width; + f->c_height = cr->c.height; + f->o_width = cr->c.left; + f->o_height = cr->c.top; + f->bottom = f->o_height + f->c_height; + f->right = f->o_width + f->c_width; + return 0; +} + +static void g2d_lock(void *prv) +{ + struct g2d_ctx *ctx = prv; + struct g2d_dev *dev = ctx->dev; + mutex_lock(&dev->mutex); +} + +static void g2d_unlock(void *prv) +{ + struct g2d_ctx *ctx = prv; + struct g2d_dev *dev = ctx->dev; + mutex_unlock(&dev->mutex); +} + +static void job_abort(void *prv) +{ + struct g2d_ctx *ctx = prv; + struct g2d_dev *dev = ctx->dev; + int ret; + + if (dev->curr == 0) /* No job currently running */ + return; + + ret = wait_event_timeout(dev->irq_queue, + dev->curr == 0, + msecs_to_jiffies(G2D_TIMEOUT)); +} + +static void device_run(void *prv) +{ + struct g2d_ctx *ctx = prv; + struct g2d_dev *dev = ctx->dev; + struct vb2_buffer *src, *dst; + u32 cmd = 0; + + dev->curr = ctx; + + src = v4l2_m2m_next_src_buf(ctx->m2m_ctx); + dst = v4l2_m2m_next_dst_buf(ctx->m2m_ctx); + + clk_enable(dev->gate); + g2d_reset(dev); + + g2d_set_src_size(dev, &ctx->in); + g2d_set_src_addr(dev, vb2_dma_contig_plane_dma_addr(src, 0)); + + g2d_set_dst_size(dev, &ctx->out); + g2d_set_dst_addr(dev, vb2_dma_contig_plane_dma_addr(dst, 0)); + + g2d_set_rop4(dev, ctx->rop); + if (ctx->in.c_width != ctx->out.c_width || + ctx->in.c_height != ctx->out.c_height) + cmd |= g2d_cmd_stretch(1); + g2d_set_cmd(dev, cmd); + g2d_start(dev); +} + +static irqreturn_t g2d_isr(int irq, void *prv) +{ + struct g2d_dev *dev = prv; + struct g2d_ctx *ctx = dev->curr; + struct vb2_buffer *src, *dst; + + g2d_clear_int(dev); + clk_disable(dev->gate); + + BUG_ON(ctx == 0); + + src = v4l2_m2m_src_buf_remove(ctx->m2m_ctx); + dst = v4l2_m2m_dst_buf_remove(ctx->m2m_ctx); + + BUG_ON(src == 0); + BUG_ON(dst == 0); + + v4l2_m2m_buf_done(src, VB2_BUF_STATE_DONE); + v4l2_m2m_buf_done(dst, VB2_BUF_STATE_DONE); + v4l2_m2m_job_finish(dev->m2m_dev, ctx->m2m_ctx); + + dev->curr = 0; + wake_up(&dev->irq_queue); + return IRQ_HANDLED; +} + +static const struct v4l2_file_operations g2d_fops = { + .owner = THIS_MODULE, + .open = g2d_open, + .release = g2d_release, + .poll = g2d_poll, + .unlocked_ioctl = video_ioctl2, + .mmap = g2d_mmap, +}; + +static const struct v4l2_ioctl_ops g2d_ioctl_ops = { + .vidioc_querycap = vidioc_querycap, + + .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt, + .vidioc_g_fmt_vid_cap = vidioc_g_fmt, + .vidioc_try_fmt_vid_cap = vidioc_try_fmt, + .vidioc_s_fmt_vid_cap = vidioc_s_fmt, + + .vidioc_enum_fmt_vid_out = vidioc_enum_fmt, + .vidioc_g_fmt_vid_out = vidioc_g_fmt, + .vidioc_try_fmt_vid_out = vidioc_try_fmt, + .vidioc_s_fmt_vid_out = vidioc_s_fmt, + + .vidioc_reqbufs = vidioc_reqbufs, + .vidioc_querybuf = vidioc_querybuf, + + .vidioc_qbuf = vidioc_qbuf, + .vidioc_dqbuf = vidioc_dqbuf, + + .vidioc_streamon = vidioc_streamon, + .vidioc_streamoff = vidioc_streamoff, + + .vidioc_g_crop = vidioc_g_crop, + .vidioc_s_crop = vidioc_s_crop, + .vidioc_cropcap = vidioc_cropcap, +}; + +static struct video_device g2d_videodev = { + .name = G2D_NAME, + .fops = &g2d_fops, + .ioctl_ops = &g2d_ioctl_ops, + .minor = -1, + .release = video_device_release, +}; + +static struct v4l2_m2m_ops g2d_m2m_ops = { + .device_run = device_run, + .job_abort = job_abort, + .lock = g2d_lock, + .unlock = g2d_unlock, +}; + +static int g2d_probe(struct platform_device *pdev) +{ + struct g2d_dev *dev; + struct video_device *vfd; + struct resource *res; + int ret = 0; + + dev = kzalloc(sizeof(*dev), GFP_KERNEL); + if (!dev) + return -ENOMEM; + spin_lock_init(&dev->irqlock); + mutex_init(&dev->mutex); + atomic_set(&dev->num_inst, 0); + init_waitqueue_head(&dev->irq_queue); + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + dev_err(&pdev->dev, "failed to find registers\n"); + ret = -ENOENT; + goto free_dev; + } + + dev->res_regs = request_mem_region(res->start, resource_size(res), + dev_name(&pdev->dev)); + + if (!dev->res_regs) { + dev_err(&pdev->dev, "failed to obtain register region\n"); + ret = -ENOENT; + goto free_dev; + } + + dev->regs = ioremap(res->start, resource_size(res)); + if (!dev->regs) { + dev_err(&pdev->dev, "failed to map registers\n"); + ret = -ENOENT; + goto rel_res_regs; + } + + dev->clk = clk_get(&pdev->dev, "sclk_fimg2d"); + if (IS_ERR_OR_NULL(dev->clk)) { + dev_err(&pdev->dev, "failed to get g2d clock\n"); + ret = -ENXIO; + goto unmap_regs; + } + + dev->gate = clk_get(&pdev->dev, "fimg2d"); + if (IS_ERR_OR_NULL(dev->gate)) { + dev_err(&pdev->dev, "failed to get g2d clock gate\n"); + ret = -ENXIO; + goto put_clk; + } + + res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); + if (!res) { + dev_err(&pdev->dev, "failed to find IRQ\n"); + ret = -ENXIO; + goto put_clk_gate; + } + + dev->irq = res->start; + + ret = request_irq(dev->irq, g2d_isr, 0, pdev->name, dev); + if (ret) { + dev_err(&pdev->dev, "failed to install IRQ\n"); + goto put_clk_gate; + } + + dev->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev); + if (IS_ERR(dev->alloc_ctx)) { + ret = PTR_ERR(dev->alloc_ctx); + goto rel_irq; + } + + ret = v4l2_device_register(&pdev->dev, &dev->v4l2_dev); + if (ret) + goto alloc_ctx_cleanup; + vfd = video_device_alloc(); + if (!vfd) { + v4l2_err(&dev->v4l2_dev, "Failed to allocate video device\n"); + ret = -ENOMEM; + goto unreg_v4l2_dev; + } + *vfd = g2d_videodev; + vfd->lock = &dev->mutex; + ret = video_register_device(vfd, VFL_TYPE_GRABBER, 0); + if (ret) { + v4l2_err(&dev->v4l2_dev, "Failed to register video device\n"); + goto rel_vdev; + } + video_set_drvdata(vfd, dev); + snprintf(vfd->name, sizeof(vfd->name), "%s", g2d_videodev.name); + dev->vfd = vfd; + v4l2_info(&dev->v4l2_dev, "device registered as /dev/video%d\n", + vfd->num); + platform_set_drvdata(pdev, dev); + dev->m2m_dev = v4l2_m2m_init(&g2d_m2m_ops); + if (IS_ERR(dev->m2m_dev)) { + v4l2_err(&dev->v4l2_dev, "Failed to init mem2mem device\n"); + ret = PTR_ERR(dev->m2m_dev); + goto unreg_video_dev; + } + + def_frame.stride = (def_frame.width * def_frame.fmt->depth) >> 3; + + return 0; + +unreg_video_dev: + video_unregister_device(dev->vfd); +rel_vdev: + video_device_release(vfd); +unreg_v4l2_dev: + v4l2_device_unregister(&dev->v4l2_dev); +alloc_ctx_cleanup: + vb2_dma_contig_cleanup_ctx(dev->alloc_ctx); +rel_irq: + free_irq(dev->irq, dev); +put_clk_gate: + clk_put(dev->gate); +put_clk: + clk_put(dev->clk); +unmap_regs: + iounmap(dev->regs); +rel_res_regs: + release_resource(dev->res_regs); +free_dev: + kfree(dev); + return ret; +} + +static int g2d_remove(struct platform_device *pdev) +{ + struct g2d_dev *dev = (struct g2d_dev *)platform_get_drvdata(pdev); + + v4l2_info(&dev->v4l2_dev, "Removing " G2D_NAME); + v4l2_m2m_release(dev->m2m_dev); + video_unregister_device(dev->vfd); + v4l2_device_unregister(&dev->v4l2_dev); + vb2_dma_contig_cleanup_ctx(dev->alloc_ctx); + free_irq(dev->irq, dev); + clk_put(dev->gate); + clk_put(dev->clk); + iounmap(dev->regs); + release_resource(dev->res_regs); + kfree(dev); + return 0; +} + +static struct platform_driver g2d_pdrv = { + .probe = g2d_probe, + .remove = g2d_remove, + .driver = { + .name = G2D_NAME, + .owner = THIS_MODULE, + }, +}; + +static void __exit g2d_exit(void) +{ + platform_driver_unregister(&g2d_pdrv); +}; + +static int __init g2d_init(void) +{ + int ret = 0; + + ret = platform_driver_register(&g2d_pdrv); + return ret; +}; + +module_init(g2d_init); +module_exit(g2d_exit); + +MODULE_AUTHOR("Kamil Debski "); +MODULE_DESCRIPTION("S5P G2D 2d graphics accelerator driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/media/video/s5p-g2d/g2d.h b/drivers/media/video/s5p-g2d/g2d.h new file mode 100644 index 0000000..5eae901 --- /dev/null +++ b/drivers/media/video/s5p-g2d/g2d.h @@ -0,0 +1,83 @@ +/* + * Samsung S5P G2D - 2D Graphics Accelerator Driver + * + * Copyright (c) 2011 Samsung Electronics Co., Ltd. + * Kamil Debski, + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the + * License, or (at your option) any later version + */ + +#include +#include + +#define G2D_NAME "s5p-g2d" + +struct g2d_dev { + struct v4l2_device v4l2_dev; + struct v4l2_m2m_dev *m2m_dev; + struct video_device *vfd; + struct mutex mutex; + spinlock_t irqlock; + atomic_t num_inst; + struct vb2_alloc_ctx *alloc_ctx; + struct resource *res_regs; + void __iomem *regs; + struct clk *clk; + struct clk *gate; + struct g2d_ctx *curr; + int irq; + wait_queue_head_t irq_queue; +}; + +struct g2d_frame { + /* Original dimensions */ + u32 width; + u32 height; + /* Crop size */ + u32 c_width; + u32 c_height; + /* Offset */ + u32 o_width; + u32 o_height; + /* Image format */ + struct g2d_fmt *fmt; + /* Variables that can calculated once and reused */ + u32 stride; + u32 bottom; + u32 right; + u32 size; +}; + +struct g2d_ctx { + struct v4l2_fh fh; + struct g2d_dev *dev; + struct v4l2_m2m_ctx *m2m_ctx; + struct g2d_frame in; + struct g2d_frame out; + struct v4l2_ctrl_handler ctrl_handler; + u32 rop; +}; + +struct g2d_fmt { + char *name; + u32 fourcc; + int depth; + u32 hw; +}; + + +void g2d_reset(struct g2d_dev *d); +void g2d_set_src_size(struct g2d_dev *d, struct g2d_frame *f); +void g2d_set_src_addr(struct g2d_dev *d, dma_addr_t a); +void g2d_set_dst_size(struct g2d_dev *d, struct g2d_frame *f); +void g2d_set_dst_addr(struct g2d_dev *d, dma_addr_t a); +void g2d_start(struct g2d_dev *d); +void g2d_clear_int(struct g2d_dev *d); +void g2d_set_rop4(struct g2d_dev *d, u32 r); +u32 g2d_cmd_stretch(u32 e); +void g2d_set_cmd(struct g2d_dev *d, u32 c); + + -- cgit v0.10.2 From 2da12fcbea0a2faa94a5d4e58eb2f0f79f9739db Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Fri, 4 Nov 2011 13:23:21 -0300 Subject: [media] tvp5150: replace video standard "magic" numbers 64933337e3cb61ca555969a35ab68b477db34ee2 [media] tvp5150: Add video format registers configuration values Added constants for each video standard supported by TVP5150, so this patch get rid of the magic numbers. Signed-off-by: Javier Martinez Canillas Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/tvp5150.c b/drivers/media/video/tvp5150.c index e927d25..2a10b03 100644 --- a/drivers/media/video/tvp5150.c +++ b/drivers/media/video/tvp5150.c @@ -702,21 +702,21 @@ static int tvp5150_set_std(struct v4l2_subdev *sd, v4l2_std_id std) /* First tests should be against specific std */ if (std == V4L2_STD_ALL) { - fmt = 0; /* Autodetect mode */ + fmt = VIDEO_STD_AUTO_SWITCH_BIT; /* Autodetect mode */ } else if (std & V4L2_STD_NTSC_443) { - fmt = 0xa; + fmt = VIDEO_STD_NTSC_4_43_BIT; } else if (std & V4L2_STD_PAL_M) { - fmt = 0x6; + fmt = VIDEO_STD_PAL_M_BIT; } else if (std & (V4L2_STD_PAL_N | V4L2_STD_PAL_Nc)) { - fmt = 0x8; + fmt = VIDEO_STD_PAL_COMBINATION_N_BIT; } else { /* Then, test against generic ones */ if (std & V4L2_STD_NTSC) - fmt = 0x2; + fmt = VIDEO_STD_NTSC_MJ_BIT; else if (std & V4L2_STD_PAL) - fmt = 0x4; + fmt = VIDEO_STD_PAL_BDGHIN_BIT; else if (std & V4L2_STD_SECAM) - fmt = 0xc; + fmt = VIDEO_STD_SECAM_BIT; } v4l2_dbg(1, debug, sd, "Set video std register to %d.\n", fmt); -- cgit v0.10.2 From 3822c7cef7b422833f1b58949a01bd87b822d280 Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Sun, 6 Nov 2011 10:24:30 -0300 Subject: [media] it913x ver 1.09 support for USB 1 devices (IT9135) IT9135 devices do support USB 1. Support added with restricton on pid count to 5. IT9137 devices wil not connect in USB 1 mode. Signed-off-by: Malcolm Priestley Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/dvb/dvb-usb/it913x.c b/drivers/media/dvb/dvb-usb/it913x.c index a541904..9f58241 100644 --- a/drivers/media/dvb/dvb-usb/it913x.c +++ b/drivers/media/dvb/dvb-usb/it913x.c @@ -350,6 +350,19 @@ static int it913x_identify_state(struct usb_device *udev, /* checnk for dual mode */ it913x_config.dual_mode = it913x_read_reg(udev, 0x49c5); + if (udev->speed != USB_SPEED_HIGH) { + props->adapter[0].fe[0].pid_filter_count = 5; + info("USB 1 low speed mode - connect to USB 2 port"); + if (pid_filter > 0) + pid_filter = 0; + if (it913x_config.dual_mode) { + it913x_config.dual_mode = 0; + info("Dual mode not supported in USB 1"); + } + } else /* For replugging */ + if(props->adapter[0].fe[0].pid_filter_count == 5) + props->adapter[0].fe[0].pid_filter_count = 31; + /* TODO different remotes */ remote = it913x_read_reg(udev, 0x49ac); /* Remote */ if (remote == 0) @@ -499,6 +512,10 @@ static int it913x_frontend_attach(struct dvb_usb_adapter *adap) int ret = 0; u8 adap_addr = I2C_BASE_ADDR + (adap->id << 5); u16 ep_size = adap->props.fe[0].stream.u.bulk.buffersize; + u8 pkt_size = 0x80; + + if (adap->dev->udev->speed != USB_SPEED_HIGH) + pkt_size = 0x10; it913x_config.adf = it913x_read_reg(udev, IO_MUX_POWER_CLK); @@ -514,13 +531,13 @@ static int it913x_frontend_attach(struct dvb_usb_adapter *adap) ret = it913x_wr_reg(udev, DEV_0, EP4_TX_LEN_LSB, ep_size & 0xff); ret = it913x_wr_reg(udev, DEV_0, EP4_TX_LEN_MSB, ep_size >> 8); - ret = it913x_wr_reg(udev, DEV_0, EP4_MAX_PKT, 0x80); + ret = it913x_wr_reg(udev, DEV_0, EP4_MAX_PKT, pkt_size); } else if (adap->id == 1 && adap->fe_adap[0].fe) { ret = it913x_wr_reg(udev, DEV_0, EP0_TX_EN, 0x6f); ret = it913x_wr_reg(udev, DEV_0, EP5_TX_LEN_LSB, ep_size & 0xff); ret = it913x_wr_reg(udev, DEV_0, EP5_TX_LEN_MSB, ep_size >> 8); - ret = it913x_wr_reg(udev, DEV_0, EP5_MAX_PKT, 0x80); + ret = it913x_wr_reg(udev, DEV_0, EP5_MAX_PKT, pkt_size); ret = it913x_wr_reg(udev, DEV_0_DMOD, MP2IF2_EN, 0x1); ret = it913x_wr_reg(udev, DEV_1_DMOD, MP2IF_SERIAL, 0x1); ret = it913x_wr_reg(udev, DEV_1, TOP_HOSTB_SER_MODE, 0x1); @@ -676,5 +693,5 @@ module_exit(it913x_module_exit); MODULE_AUTHOR("Malcolm Priestley "); MODULE_DESCRIPTION("it913x USB 2 Driver"); -MODULE_VERSION("1.08"); +MODULE_VERSION("1.09"); MODULE_LICENSE("GPL"); -- cgit v0.10.2 From de2843b663fd621e9a6c75fed4da73e8c9a1b094 Mon Sep 17 00:00:00 2001 From: Peter De Schrijver Date: Sun, 6 Nov 2011 10:15:47 -0300 Subject: [media] bt8xx: add support for Tongwei Video Technology TD-3116 The following patch adds support for the Tongwei Video Technology TD-3116 board. This is a Bt878 based capture card with 16 inputs meant for surveilance applications. It also offers a way to check which inputs have a video signal while capturing another input. In addition there are a number of alarm inputs and outputs available and there is microcontroller which is presumably intended for use as a system watchdog. None of these extra capabilities are supported by the patch. Signed-off-by: Peter De Schrijver Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/bt8xx/bttv-cards.c b/drivers/media/video/bt8xx/bttv-cards.c index 076b7f2..ff2933a 100644 --- a/drivers/media/video/bt8xx/bttv-cards.c +++ b/drivers/media/video/bt8xx/bttv-cards.c @@ -80,6 +80,8 @@ static void phytec_muxsel(struct bttv *btv, unsigned int input); static void gv800s_muxsel(struct bttv *btv, unsigned int input); static void gv800s_init(struct bttv *btv); +static void td3116_muxsel(struct bttv *btv, unsigned int input); + static int terratec_active_radio_upgrade(struct bttv *btv); static int tea5757_read(struct bttv *btv); static int tea5757_write(struct bttv *btv, int value); @@ -342,6 +344,7 @@ static struct CARD { { 0x15401835, BTTV_BOARD_PV183, "Provideo PV183-6" }, { 0x15401836, BTTV_BOARD_PV183, "Provideo PV183-7" }, { 0x15401837, BTTV_BOARD_PV183, "Provideo PV183-8" }, + { 0x3116f200, BTTV_BOARD_TVT_TD3116, "Tongwei Video Technology TD-3116" }, { 0, -1, NULL } }; @@ -2880,6 +2883,16 @@ struct tvcard bttv_tvcards[] = { .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, }, + [BTTV_BOARD_TVT_TD3116] = { + .name = "Tongwei Video Technology TD-3116", + .video_inputs = 16, + .gpiomask = 0xc00ff, + .muxsel = MUXSEL(2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2), + .muxsel_hook = td3116_muxsel, + .svhs = NO_SVHS, + .pll = PLL_28, + .tuner_type = TUNER_ABSENT, + }, }; static const unsigned int bttv_num_tvcards = ARRAY_SIZE(bttv_tvcards); @@ -3229,6 +3242,42 @@ static void geovision_muxsel(struct bttv *btv, unsigned int input) gpio_bits(0xf, inmux); } +/* + * The TD3116 has 2 74HC4051 muxes wired to the MUX0 input of a bt878. + * The first 74HC4051 has the lower 8 inputs, the second one the higher 8. + * The muxes are controlled via a 74HC373 latch which is connected to + * GPIOs 0-7. GPIO 18 is connected to the LE signal of the latch. + * Q0 of the latch is connected to the Enable (~E) input of the first + * 74HC4051. Q1 - Q3 are connected to S0 - S2 of the same 74HC4051. + * Q4 - Q7 are connected to the second 74HC4051 in the same way. + */ + +static void td3116_latch_value(struct bttv *btv, u32 value) +{ + gpio_bits((1<<18) | 0xff, value); + gpio_bits((1<<18) | 0xff, (1<<18) | value); + udelay(1); + gpio_bits((1<<18) | 0xff, value); +} + +static void td3116_muxsel(struct bttv *btv, unsigned int input) +{ + u32 value; + u32 highbit; + + highbit = (input & 0x8) >> 3 ; + + /* Disable outputs and set value in the mux */ + value = 0x11; /* Disable outputs */ + value |= ((input & 0x7) << 1) << (4 * highbit); + td3116_latch_value(btv, value); + + /* Enable the correct output */ + value &= ~0x11; + value |= ((highbit ^ 0x1) << 4) | highbit; + td3116_latch_value(btv, value); +} + /* ----------------------------------------------------------------------- */ static void bttv_reset_audio(struct bttv *btv) diff --git a/drivers/media/video/bt8xx/bttv.h b/drivers/media/video/bt8xx/bttv.h index 4db8b7d..c517161 100644 --- a/drivers/media/video/bt8xx/bttv.h +++ b/drivers/media/video/bt8xx/bttv.h @@ -183,6 +183,7 @@ #define BTTV_BOARD_GEOVISION_GV800S 0x9d #define BTTV_BOARD_GEOVISION_GV800S_SL 0x9e #define BTTV_BOARD_PV183 0x9f +#define BTTV_BOARD_TVT_TD3116 0xa0 /* more card-specific defines */ -- cgit v0.10.2 From c540d9f13d1f0f6913434b0b8241bb6270818769 Mon Sep 17 00:00:00 2001 From: Peter De Schrijver Date: Sun, 6 Nov 2011 10:47:58 -0300 Subject: [media] bt8xx: add support for PCI device ID 0x36c add support for conexant PCI device 0x36c. Seems to be fully compatible with the currently supported chips, yet the chip has different PCI ID. Signed-off-by: Peter De Schrijver Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/bt8xx/bt848.h b/drivers/media/video/bt8xx/bt848.h index 0bcd953..c37e6ac 100644 --- a/drivers/media/video/bt8xx/bt848.h +++ b/drivers/media/video/bt8xx/bt848.h @@ -30,6 +30,10 @@ #ifndef PCI_DEVICE_ID_BT849 #define PCI_DEVICE_ID_BT849 0x351 #endif +#ifndef PCI_DEVICE_ID_FUSION879 +#define PCI_DEVICE_ID_FUSION879 0x36c +#endif + #ifndef PCI_DEVICE_ID_BT878 #define PCI_DEVICE_ID_BT878 0x36e #endif @@ -37,7 +41,6 @@ #define PCI_DEVICE_ID_BT879 0x36f #endif - /* Brooktree 848 registers */ #define BT848_DSTATUS 0x000 diff --git a/drivers/media/video/bt8xx/bttv-driver.c b/drivers/media/video/bt8xx/bttv-driver.c index 3dd0660..76c301f 100644 --- a/drivers/media/video/bt8xx/bttv-driver.c +++ b/drivers/media/video/bt8xx/bttv-driver.c @@ -4572,6 +4572,7 @@ static struct pci_device_id bttv_pci_tbl[] = { {PCI_VDEVICE(BROOKTREE, PCI_DEVICE_ID_BT849), 0}, {PCI_VDEVICE(BROOKTREE, PCI_DEVICE_ID_BT878), 0}, {PCI_VDEVICE(BROOKTREE, PCI_DEVICE_ID_BT879), 0}, + {PCI_VDEVICE(BROOKTREE, PCI_DEVICE_ID_FUSION879), 0}, {0,} }; -- cgit v0.10.2 From 3339a5b165c2769a84346cac342ade67d7b7a510 Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Sun, 6 Nov 2011 11:19:14 -0300 Subject: [media] it913x-fe ver 1.10 correct SNR reading from frontend Correction of reading from frontend and represents a SNR nonlinear scale of minimum signal to full signal. Signed-off-by: Malcolm Priestley Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/dvb/frontends/it913x-fe.c b/drivers/media/dvb/frontends/it913x-fe.c index 6d12dcc..07c1b46 100644 --- a/drivers/media/dvb/frontends/it913x-fe.c +++ b/drivers/media/dvb/frontends/it913x-fe.c @@ -53,6 +53,8 @@ struct it913x_fe_state { struct ite_config *config; u8 i2c_addr; u32 frequency; + fe_modulation_t constellation; + fe_transmit_mode_t transmission_mode; u32 crystalFrequency; u32 adcFrequency; u8 tuner_type; @@ -496,14 +498,50 @@ static int it913x_fe_read_signal_strength(struct dvb_frontend *fe, return 0; } -static int it913x_fe_read_snr(struct dvb_frontend *fe, u16* snr) +static int it913x_fe_read_snr(struct dvb_frontend *fe, u16 *snr) { struct it913x_fe_state *state = fe->demodulator_priv; - int ret = it913x_read_reg_u8(state, SIGNAL_QUALITY); - ret = (ret * 0xff) / 0x64; - ret |= (ret << 0x8); - *snr = ~ret; - return 0; + int ret; + u8 reg[3]; + u32 snr_val, snr_min, snr_max; + u32 temp; + + ret = it913x_read_reg(state, 0x2c, reg, sizeof(reg)); + + snr_val = (u32)(reg[2] << 16) | (reg[1] < 8) | reg[0]; + + ret |= it913x_read_reg(state, 0xf78b, reg, 1); + if (reg[0]) + snr_val /= reg[0]; + + if (state->transmission_mode == TRANSMISSION_MODE_2K) + snr_val *= 4; + else if (state->transmission_mode == TRANSMISSION_MODE_4K) + snr_val *= 2; + + if (state->constellation == QPSK) { + snr_min = 0xb4711; + snr_max = 0x191451; + } else if (state->constellation == QAM_16) { + snr_min = 0x4f0d5; + snr_max = 0xc7925; + } else if (state->constellation == QAM_64) { + snr_min = 0x256d0; + snr_max = 0x626be; + } else + return -EINVAL; + + if (snr_val < snr_min) + *snr = 0; + else if (snr_val < snr_max) { + temp = (snr_val - snr_min) >> 5; + temp *= 0xffff; + temp /= (snr_max - snr_min) >> 5; + *snr = (u16)temp; + } else + *snr = 0xffff; + + return (ret < 0) ? -ENODEV : 0; } static int it913x_fe_read_ber(struct dvb_frontend *fe, u32 *ber) @@ -530,9 +568,13 @@ static int it913x_fe_get_frontend(struct dvb_frontend *fe, if (reg[3] < 3) p->u.ofdm.constellation = fe_con[reg[3]]; + state->constellation = p->u.ofdm.constellation; + if (reg[0] < 3) p->u.ofdm.transmission_mode = fe_mode[reg[0]]; + state->transmission_mode = p->u.ofdm.transmission_mode; + if (reg[1] < 4) p->u.ofdm.guard_interval = fe_gi[reg[1]]; @@ -888,5 +930,5 @@ static struct dvb_frontend_ops it913x_fe_ofdm_ops = { MODULE_DESCRIPTION("it913x Frontend and it9137 tuner"); MODULE_AUTHOR("Malcolm Priestley tvboxspy@gmail.com"); -MODULE_VERSION("1.09"); +MODULE_VERSION("1.10"); MODULE_LICENSE("GPL"); -- cgit v0.10.2 From 7f033e3354b40fdb5c4c8a15cce733cecd0f963a Mon Sep 17 00:00:00 2001 From: Piotr Chmura Date: Sun, 6 Nov 2011 16:31:38 -0300 Subject: [media] staging: as102: Remove comment tags for editors configuration Cc: Devin Heitmueller Signed-off-by: Piotr Chmura Signed-off-by: Sylwester Nawrocki Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/staging/media/as102/as102_drv.c b/drivers/staging/media/as102/as102_drv.c index d335c7d..771d550 100644 --- a/drivers/staging/media/as102/as102_drv.c +++ b/drivers/staging/media/as102/as102_drv.c @@ -347,5 +347,3 @@ module_exit(as102_driver_exit); MODULE_DESCRIPTION(DRIVER_FULL_NAME); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Pierrick Hascoet "); - -/* EOF - vim: set textwidth=80 ts=8 sw=8 sts=8 noet: */ diff --git a/drivers/staging/media/as102/as102_drv.h b/drivers/staging/media/as102/as102_drv.h index bcda635..7f56f64 100644 --- a/drivers/staging/media/as102/as102_drv.h +++ b/drivers/staging/media/as102/as102_drv.h @@ -137,5 +137,3 @@ void as102_dvb_unregister(struct as102_dev_t *dev); int as102_dvb_register_fe(struct as102_dev_t *dev, struct dvb_frontend *fe); int as102_dvb_unregister_fe(struct dvb_frontend *dev); - -/* EOF - vim: set textwidth=80 ts=8 sw=8 sts=8 noet: */ diff --git a/drivers/staging/media/as102/as102_fe.c b/drivers/staging/media/as102/as102_fe.c index 3550f90..7d7dd55 100644 --- a/drivers/staging/media/as102/as102_fe.c +++ b/drivers/staging/media/as102/as102_fe.c @@ -599,5 +599,3 @@ static void as102_fe_copy_tune_parameters(struct as10x_tune_args *tune_args, as102_fe_get_code_rate(params->u.ofdm.code_rate_HP); } } - -/* EOF - vim: set textwidth=80 ts=8 sw=8 sts=8 noet: */ diff --git a/drivers/staging/media/as102/as102_fw.c b/drivers/staging/media/as102/as102_fw.c index c019df9..4fb2987 100644 --- a/drivers/staging/media/as102/as102_fw.c +++ b/drivers/staging/media/as102/as102_fw.c @@ -247,5 +247,3 @@ error: return errno; } #endif - -/* EOF - vim: set textwidth=80 ts=8 sw=8 sts=8 noet: */ diff --git a/drivers/staging/media/as102/as102_fw.h b/drivers/staging/media/as102/as102_fw.h index 27e5347..951a1fa 100644 --- a/drivers/staging/media/as102/as102_fw.h +++ b/drivers/staging/media/as102/as102_fw.h @@ -38,5 +38,3 @@ struct as10x_fw_pkt_t { #ifdef __KERNEL__ int as102_fw_upload(struct as102_bus_adapter_t *bus_adap); #endif - -/* EOF - vim: set textwidth=80 ts=8 sw=8 sts=8 noet: */ diff --git a/drivers/staging/media/as102/as102_usb_drv.c b/drivers/staging/media/as102/as102_usb_drv.c index 264be2d..0a8f12b 100644 --- a/drivers/staging/media/as102/as102_usb_drv.c +++ b/drivers/staging/media/as102/as102_usb_drv.c @@ -474,5 +474,3 @@ static int as102_release(struct inode *inode, struct file *file) } MODULE_DEVICE_TABLE(usb, as102_usb_id_table); - -/* EOF - vim: set textwidth=80 ts=8 sw=8 sts=8 noet: */ diff --git a/drivers/staging/media/as102/as102_usb_drv.h b/drivers/staging/media/as102/as102_usb_drv.h index fb1fc41..35925b7 100644 --- a/drivers/staging/media/as102/as102_usb_drv.h +++ b/drivers/staging/media/as102/as102_usb_drv.h @@ -56,4 +56,3 @@ struct as10x_usb_token_cmd_t { struct as10x_cmd_t r; }; #endif -/* EOF - vim: set textwidth=80 ts=8 sw=8 sts=8 noet: */ diff --git a/drivers/staging/media/as102/as10x_cmd.h b/drivers/staging/media/as102/as10x_cmd.h index 01a7163..6f837b1 100644 --- a/drivers/staging/media/as102/as10x_cmd.h +++ b/drivers/staging/media/as102/as10x_cmd.h @@ -537,4 +537,3 @@ int as10x_context_rsp_parse(struct as10x_cmd_t *prsp, uint16_t proc_id); } #endif #endif -/* EOF - vim: set textwidth=80 ts=3 sw=3 sts=3 et: */ -- cgit v0.10.2 From c06271e052cd00217a26d5aadfa7cf937eaa97a6 Mon Sep 17 00:00:00 2001 From: Sylwester Nawrocki Date: Sun, 6 Nov 2011 16:31:39 -0300 Subject: [media] staging: as102: Remove unnecessary typedefs According to the kernel coding rules typedefs should be avoided, so replace theit occurances with explicit enum/union types. Cc: Devin Heitmueller Signed-off-by: Sylwester Nawrocki Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/staging/media/as102/as10x_cmd.h b/drivers/staging/media/as102/as10x_cmd.h index 6f837b1..8f13bea 100644 --- a/drivers/staging/media/as102/as10x_cmd.h +++ b/drivers/staging/media/as102/as10x_cmd.h @@ -52,7 +52,7 @@ /*********************************/ /* TYPE DEFINITION */ /*********************************/ -typedef enum { +enum control_proc { CONTROL_PROC_TURNON = 0x0001, CONTROL_PROC_TURNON_RSP = 0x0100, CONTROL_PROC_SET_REGISTER = 0x0002, @@ -92,11 +92,11 @@ typedef enum { CONTROL_PROC_DUMPLOG_MEMORY_RSP = 0xFE00, CONTROL_PROC_TURNOFF = 0x00FF, CONTROL_PROC_TURNOFF_RSP = 0xFF00 -} control_proc; +}; #pragma pack(1) -typedef union { +union as10x_turn_on { /* request */ struct { /* request identifier */ @@ -109,9 +109,9 @@ typedef union { /* error */ uint8_t error; } rsp; -} TURN_ON; +}; -typedef union { +union as10x_turn_off { /* request */ struct { /* request identifier */ @@ -124,9 +124,9 @@ typedef union { /* error */ uint8_t err; } rsp; -} TURN_OFF; +}; -typedef union { +union as10x_set_tune { /* request */ struct { /* request identifier */ @@ -141,9 +141,9 @@ typedef union { /* response error */ uint8_t error; } rsp; -} SET_TUNE; +}; -typedef union { +union as10x_get_tune_status { /* request */ struct { /* request identifier */ @@ -158,9 +158,9 @@ typedef union { /* tune status */ struct as10x_tune_status sts; } rsp; -} GET_TUNE_STATUS; +}; -typedef union { +union as10x_get_tps { /* request */ struct { /* request identifier */ @@ -175,9 +175,9 @@ typedef union { /* tps details */ struct as10x_tps tps; } rsp; -} GET_TPS; +}; -typedef union { +union as10x_common { /* request */ struct { /* request identifier */ @@ -190,9 +190,9 @@ typedef union { /* response error */ uint8_t error; } rsp; -} COMMON; +}; -typedef union { +union as10x_add_pid_filter { /* request */ struct { /* request identifier */ @@ -213,9 +213,9 @@ typedef union { /* Filter id */ uint8_t filter_id; } rsp; -} ADD_PID_FILTER; +}; -typedef union { +union as10x_del_pid_filter { /* request */ struct { /* request identifier */ @@ -230,9 +230,9 @@ typedef union { /* response error */ uint8_t error; } rsp; -} DEL_PID_FILTER; +}; -typedef union { +union as10x_start_streaming { /* request */ struct { /* request identifier */ @@ -245,9 +245,9 @@ typedef union { /* error */ uint8_t error; } rsp; -} START_STREAMING; +}; -typedef union { +union as10x_stop_streaming { /* request */ struct { /* request identifier */ @@ -260,9 +260,9 @@ typedef union { /* error */ uint8_t error; } rsp; -} STOP_STREAMING; +}; -typedef union { +union as10x_get_demod_stats { /* request */ struct { /* request identifier */ @@ -277,9 +277,9 @@ typedef union { /* demod stats */ struct as10x_demod_stats stats; } rsp; -} GET_DEMOD_STATS; +}; -typedef union { +union as10x_get_impulse_resp { /* request */ struct { /* request identifier */ @@ -294,9 +294,9 @@ typedef union { /* impulse response ready */ uint8_t is_ready; } rsp; -} GET_IMPULSE_RESP; +}; -typedef union { +union as10x_fw_context { /* request */ struct { /* request identifier */ @@ -319,9 +319,9 @@ typedef union { /* error */ uint8_t error; } rsp; -} FW_CONTEXT; +}; -typedef union { +union as10x_set_register { /* request */ struct { /* response identifier */ @@ -338,9 +338,9 @@ typedef union { /* error */ uint8_t error; } rsp; -} SET_REGISTER; +}; -typedef union { +union as10x_get_register { /* request */ struct { /* response identifier */ @@ -357,9 +357,9 @@ typedef union { /* register content */ struct as10x_register_value reg_val; } rsp; -} GET_REGISTER; +}; -typedef union { +union as10x_cfg_change_mode { /* request */ struct { /* request identifier */ @@ -374,7 +374,7 @@ typedef union { /* error */ uint8_t error; } rsp; -} CFG_CHANGE_MODE; +}; struct as10x_cmd_header_t { uint16_t req_id; @@ -384,7 +384,8 @@ struct as10x_cmd_header_t { }; #define DUMP_BLOCK_SIZE 16 -typedef union { + +union as10x_dump_memory { /* request */ struct { /* request identifier */ @@ -411,9 +412,9 @@ typedef union { uint32_t data32[DUMP_BLOCK_SIZE / sizeof(uint32_t)]; } u; } rsp; -} DUMP_MEMORY; +}; -typedef union { +union as10x_dumplog_memory { struct { /* request identifier */ uint16_t proc_id; @@ -430,9 +431,9 @@ typedef union { /* dump data */ uint8_t data[DUMP_BLOCK_SIZE]; } rsp; -} DUMPLOG_MEMORY; +}; -typedef union { +union as10x_raw_data { /* request */ struct { uint16_t proc_id; @@ -445,33 +446,31 @@ typedef union { uint8_t data[64 - sizeof(struct as10x_cmd_header_t) /* header */ - 2 /* proc_id */ - 1 /* rc */]; } rsp; -} RAW_DATA; +}; struct as10x_cmd_t { - /* header */ - struct as10x_cmd_header_t header; - /* body */ - union { - TURN_ON turn_on; - TURN_OFF turn_off; - SET_TUNE set_tune; - GET_TUNE_STATUS get_tune_status; - GET_TPS get_tps; - COMMON common; - ADD_PID_FILTER add_pid_filter; - DEL_PID_FILTER del_pid_filter; - START_STREAMING start_streaming; - STOP_STREAMING stop_streaming; - GET_DEMOD_STATS get_demod_stats; - GET_IMPULSE_RESP get_impulse_rsp; - FW_CONTEXT context; - SET_REGISTER set_register; - GET_REGISTER get_register; - CFG_CHANGE_MODE cfg_change_mode; - DUMP_MEMORY dump_memory; - DUMPLOG_MEMORY dumplog_memory; - RAW_DATA raw_data; - } body; + struct as10x_cmd_header_t header; + union { + union as10x_turn_on turn_on; + union as10x_turn_off turn_off; + union as10x_set_tune set_tune; + union as10x_get_tune_status get_tune_status; + union as10x_get_tps get_tps; + union as10x_common common; + union as10x_add_pid_filter add_pid_filter; + union as10x_del_pid_filter del_pid_filter; + union as10x_start_streaming start_streaming; + union as10x_stop_streaming stop_streaming; + union as10x_get_demod_stats get_demod_stats; + union as10x_get_impulse_resp get_impulse_rsp; + union as10x_fw_context context; + union as10x_set_register set_register; + union as10x_get_register get_register; + union as10x_cfg_change_mode cfg_change_mode; + union as10x_dump_memory dump_memory; + union as10x_dumplog_memory dumplog_memory; + union as10x_raw_data raw_data; + } body; }; struct as10x_token_cmd_t { -- cgit v0.10.2 From 82aae98df488c15c212059b23460fe9a9dd97412 Mon Sep 17 00:00:00 2001 From: Sylwester Nawrocki Date: Sun, 6 Nov 2011 16:31:40 -0300 Subject: [media] staging: as102: Remove leftovers of the SPI bus driver SPI bus driver support is not included in this module, the SPI driver files are missing. But some bits are still present so clean up the unused code. The SPI driver support can be properly added later if needed. Then CONFIG_AS102_SPI and CONFIG_AS102_USB is now not needed and the pre-processor statements using these config options can now be removed from *.c files. Cc: Devin Heitmueller Signed-off-by: Sylwester Nawrocki Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/staging/media/as102/Makefile b/drivers/staging/media/as102/Makefile index e7dbb6f..1bca43e8 100644 --- a/drivers/staging/media/as102/Makefile +++ b/drivers/staging/media/as102/Makefile @@ -3,4 +3,4 @@ dvb-as102-objs := as102_drv.o as102_fw.o as10x_cmd.o as10x_cmd_stream.o \ obj-$(CONFIG_DVB_AS102) += dvb-as102.o -EXTRA_CFLAGS += -DCONFIG_AS102_USB -Idrivers/media/dvb/dvb-core +EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core diff --git a/drivers/staging/media/as102/as102_drv.c b/drivers/staging/media/as102/as102_drv.c index 771d550..0bcc55c 100644 --- a/drivers/staging/media/as102/as102_drv.c +++ b/drivers/staging/media/as102/as102_drv.c @@ -56,9 +56,7 @@ int elna_enable = 1; module_param_named(elna_enable, elna_enable, int, 0644); MODULE_PARM_DESC(elna_enable, "Activate eLNA (default: on)"); -#ifdef DVB_DEFINE_MOD_OPT_ADAPTER_NR DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); -#endif static void as102_stop_stream(struct as102_dev_t *dev) { @@ -203,16 +201,8 @@ int as102_dvb_register(struct as102_dev_t *as102_dev) ret = dvb_register_adapter(&as102_dev->dvb_adap, as102_dev->name, THIS_MODULE, -#if defined(CONFIG_AS102_USB) - &as102_dev->bus_adap.usb_dev->dev -#elif defined(CONFIG_AS102_SPI) - &as102_dev->bus_adap.spi_dev->dev -#else -#error >>> dvb_register_adapter <<< -#endif -#ifdef DVB_DEFINE_MOD_OPT_ADAPTER_NR - , adapter_nr -#endif + &as102_dev->bus_adap.usb_dev->dev, + adapter_nr ); if (ret < 0) { err("%s: dvb_register_adapter() failed (errno = %d)", @@ -294,23 +284,13 @@ void as102_dvb_unregister(struct as102_dev_t *as102_dev) static int __init as102_driver_init(void) { - int ret = 0; - - ENTER(); + int ret; /* register this driver with the low level subsystem */ -#if defined(CONFIG_AS102_USB) ret = usb_register(&as102_usb_driver); if (ret) err("usb_register failed (ret = %d)", ret); -#endif -#if defined(CONFIG_AS102_SPI) - ret = spi_register_driver(&as102_spi_driver); - if (ret) - printk(KERN_ERR "spi_register failed (ret = %d)", ret); -#endif - LEAVE(); return ret; } @@ -327,15 +307,8 @@ module_init(as102_driver_init); */ static void __exit as102_driver_exit(void) { - ENTER(); /* deregister this driver with the low level bus subsystem */ -#if defined(CONFIG_AS102_USB) usb_deregister(&as102_usb_driver); -#endif -#if defined(CONFIG_AS102_SPI) - spi_unregister_driver(&as102_spi_driver); -#endif - LEAVE(); } /* diff --git a/drivers/staging/media/as102/as102_drv.h b/drivers/staging/media/as102/as102_drv.h index 7f56f64..af2bf1e 100644 --- a/drivers/staging/media/as102/as102_drv.h +++ b/drivers/staging/media/as102/as102_drv.h @@ -17,27 +17,18 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#if defined(CONFIG_AS102_USB) #include -extern struct usb_driver as102_usb_driver; -#endif - -#if defined(CONFIG_AS102_SPI) -#include -#include -#include - -extern struct spi_driver as102_spi_driver; -#endif - -#include "dvb_demux.h" -#include "dvb_frontend.h" -#include "dmxdev.h" +#include +#include +#include +#include "as10x_cmd.h" +#include "as102_usb_drv.h" #define DRIVER_FULL_NAME "Abilis Systems as10x usb driver" #define DRIVER_NAME "as10x_usb" extern int debug; +extern struct usb_driver as102_usb_driver; #define dprintk(debug, args...) \ do { if (debug) { \ @@ -58,39 +49,14 @@ extern int debug; #define AS102_USB_BUF_SIZE 512 #define MAX_STREAM_URB 32 -#include "as10x_cmd.h" - -#if defined(CONFIG_AS102_USB) -#include "as102_usb_drv.h" -#endif - -#if defined(CONFIG_AS102_SPI) -#include "as10x_spi_drv.h" -#endif - - struct as102_bus_adapter_t { -#if defined(CONFIG_AS102_USB) struct usb_device *usb_dev; -#elif defined(CONFIG_AS102_SPI) - struct spi_device *spi_dev; - struct cdev cdev; /* spidev raw device */ - - struct timer_list timer; - struct completion xfer_done; -#endif /* bus token lock */ struct mutex lock; /* low level interface for bus adapter */ union as10x_bus_token_t { -#if defined(CONFIG_AS102_USB) /* usb token */ struct as10x_usb_token_cmd_t usb; -#endif -#if defined(CONFIG_AS102_SPI) - /* spi token */ - struct as10x_spi_token_cmd_t spi; -#endif } token; /* token cmd xfer id */ diff --git a/drivers/staging/media/as102/as102_fw.c b/drivers/staging/media/as102/as102_fw.c index 4fb2987..3aa4aad 100644 --- a/drivers/staging/media/as102/as102_fw.c +++ b/drivers/staging/media/as102/as102_fw.c @@ -169,13 +169,8 @@ int as102_fw_upload(struct as102_bus_adapter_t *bus_adap) const struct firmware *firmware; unsigned char *cmd_buf = NULL; char *fw1, *fw2; - -#if defined(CONFIG_AS102_USB) struct usb_device *dev = bus_adap->usb_dev; -#endif -#if defined(CONFIG_AS102_SPI) - struct spi_device *dev = bus_adap->spi_dev; -#endif + ENTER(); /* select fw file to upload */ -- cgit v0.10.2 From 57753767dda8a0f415555da3d94947d2687bc421 Mon Sep 17 00:00:00 2001 From: Sylwester Nawrocki Date: Sun, 6 Nov 2011 16:31:41 -0300 Subject: [media] staging: as102: Make the driver select CONFIG_FW_LOADER It doesn't seem to be of much advantage to compile in FW_LOADER support conditionally, then make the driver always select FW_LOADER and remove #idefs from the code. Cc: Devin Heitmueller Signed-off-by: Sylwester Nawrocki Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/staging/media/as102/Kconfig b/drivers/staging/media/as102/Kconfig index 5865029..28aba00 100644 --- a/drivers/staging/media/as102/Kconfig +++ b/drivers/staging/media/as102/Kconfig @@ -1,6 +1,7 @@ config DVB_AS102 tristate "Abilis AS102 DVB receiver" depends on DVB_CORE && USB && I2C && INPUT + select FW_LOADER help Choose Y or M here if you have a device containing an AS102 diff --git a/drivers/staging/media/as102/as102_drv.c b/drivers/staging/media/as102/as102_drv.c index 0bcc55c..85f58b9 100644 --- a/drivers/staging/media/as102/as102_drv.c +++ b/drivers/staging/media/as102/as102_drv.c @@ -249,7 +249,6 @@ int as102_dvb_register(struct as102_dev_t *as102_dev) /* init start / stop stream mutex */ mutex_init(&as102_dev->sem); -#if defined(CONFIG_FW_LOADER) || defined(CONFIG_FW_LOADER_MODULE) /* * try to load as102 firmware. If firmware upload failed, we'll be * able to upload it later. @@ -257,8 +256,6 @@ int as102_dvb_register(struct as102_dev_t *as102_dev) if (fw_upload) try_then_request_module(as102_fw_upload(&as102_dev->bus_adap), "firmware_class"); -#endif - failed: LEAVE(); /* FIXME: free dvb_XXX */ diff --git a/drivers/staging/media/as102/as102_fw.c b/drivers/staging/media/as102/as102_fw.c index 3aa4aad..ab7dcdb 100644 --- a/drivers/staging/media/as102/as102_fw.c +++ b/drivers/staging/media/as102/as102_fw.c @@ -26,7 +26,6 @@ #include "as102_drv.h" #include "as102_fw.h" -#if defined(CONFIG_FW_LOADER) || defined(CONFIG_FW_LOADER_MODULE) char as102_st_fw1[] = "as102_data1_st.hex"; char as102_st_fw2[] = "as102_data2_st.hex"; char as102_dt_fw1[] = "as102_data1_dt.hex"; @@ -182,7 +181,6 @@ int as102_fw_upload(struct as102_bus_adapter_t *bus_adap) fw2 = as102_st_fw2; } -#if defined(CONFIG_FW_LOADER) || defined(CONFIG_FW_LOADER_MODULE) /* allocate buffer to store firmware upload command and data */ cmd_buf = kzalloc(MAX_FW_PKT_SIZE, GFP_KERNEL); if (cmd_buf == NULL) { @@ -237,8 +235,7 @@ error: /* release firmware if needed */ if (firmware != NULL) release_firmware(firmware); -#endif + LEAVE(); return errno; } -#endif -- cgit v0.10.2 From fa1a13f621c6de8c3a6e6fa8b3dd66094f0f660a Mon Sep 17 00:00:00 2001 From: Sylwester Nawrocki Date: Sun, 6 Nov 2011 16:31:42 -0300 Subject: [media] staging: as102: Replace pragma(pack) with attribute __packed Cc: Devin Heitmueller Signed-off-by: Sylwester Nawrocki Signed-off-by: Piotr Chmura Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/staging/media/as102/as102_fw.h b/drivers/staging/media/as102/as102_fw.h index 951a1fa..a1fdb92 100644 --- a/drivers/staging/media/as102/as102_fw.h +++ b/drivers/staging/media/as102/as102_fw.h @@ -20,11 +20,10 @@ extern int dual_tuner; -#pragma pack(1) struct as10x_raw_fw_pkt { unsigned char address[4]; unsigned char data[MAX_FW_PKT_SIZE - 6]; -}; +} __packed; struct as10x_fw_pkt_t { union { @@ -32,8 +31,7 @@ struct as10x_fw_pkt_t { unsigned char length[2]; } u; struct as10x_raw_fw_pkt raw; -}; -#pragma pack() +} __packed; #ifdef __KERNEL__ int as102_fw_upload(struct as102_bus_adapter_t *bus_adap); diff --git a/drivers/staging/media/as102/as10x_cmd.h b/drivers/staging/media/as102/as10x_cmd.h index 8f13bea..05f7150 100644 --- a/drivers/staging/media/as102/as10x_cmd.h +++ b/drivers/staging/media/as102/as10x_cmd.h @@ -94,8 +94,6 @@ enum control_proc { CONTROL_PROC_TURNOFF_RSP = 0xFF00 }; - -#pragma pack(1) union as10x_turn_on { /* request */ struct { @@ -109,7 +107,7 @@ union as10x_turn_on { /* error */ uint8_t error; } rsp; -}; +} __packed; union as10x_turn_off { /* request */ @@ -124,7 +122,7 @@ union as10x_turn_off { /* error */ uint8_t err; } rsp; -}; +} __packed; union as10x_set_tune { /* request */ @@ -141,7 +139,7 @@ union as10x_set_tune { /* response error */ uint8_t error; } rsp; -}; +} __packed; union as10x_get_tune_status { /* request */ @@ -158,7 +156,7 @@ union as10x_get_tune_status { /* tune status */ struct as10x_tune_status sts; } rsp; -}; +} __packed; union as10x_get_tps { /* request */ @@ -175,7 +173,7 @@ union as10x_get_tps { /* tps details */ struct as10x_tps tps; } rsp; -}; +} __packed; union as10x_common { /* request */ @@ -190,7 +188,7 @@ union as10x_common { /* response error */ uint8_t error; } rsp; -}; +} __packed; union as10x_add_pid_filter { /* request */ @@ -213,7 +211,7 @@ union as10x_add_pid_filter { /* Filter id */ uint8_t filter_id; } rsp; -}; +} __packed; union as10x_del_pid_filter { /* request */ @@ -230,7 +228,7 @@ union as10x_del_pid_filter { /* response error */ uint8_t error; } rsp; -}; +} __packed; union as10x_start_streaming { /* request */ @@ -245,7 +243,7 @@ union as10x_start_streaming { /* error */ uint8_t error; } rsp; -}; +} __packed; union as10x_stop_streaming { /* request */ @@ -260,7 +258,7 @@ union as10x_stop_streaming { /* error */ uint8_t error; } rsp; -}; +} __packed; union as10x_get_demod_stats { /* request */ @@ -277,7 +275,7 @@ union as10x_get_demod_stats { /* demod stats */ struct as10x_demod_stats stats; } rsp; -}; +} __packed; union as10x_get_impulse_resp { /* request */ @@ -294,7 +292,7 @@ union as10x_get_impulse_resp { /* impulse response ready */ uint8_t is_ready; } rsp; -}; +} __packed; union as10x_fw_context { /* request */ @@ -319,7 +317,7 @@ union as10x_fw_context { /* error */ uint8_t error; } rsp; -}; +} __packed; union as10x_set_register { /* request */ @@ -338,7 +336,7 @@ union as10x_set_register { /* error */ uint8_t error; } rsp; -}; +} __packed; union as10x_get_register { /* request */ @@ -357,7 +355,7 @@ union as10x_get_register { /* register content */ struct as10x_register_value reg_val; } rsp; -}; +} __packed; union as10x_cfg_change_mode { /* request */ @@ -374,14 +372,14 @@ union as10x_cfg_change_mode { /* error */ uint8_t error; } rsp; -}; +} __packed; struct as10x_cmd_header_t { uint16_t req_id; uint16_t prog; uint16_t version; uint16_t data_len; -}; +} __packed; #define DUMP_BLOCK_SIZE 16 @@ -412,7 +410,7 @@ union as10x_dump_memory { uint32_t data32[DUMP_BLOCK_SIZE / sizeof(uint32_t)]; } u; } rsp; -}; +} __packed; union as10x_dumplog_memory { struct { @@ -431,7 +429,7 @@ union as10x_dumplog_memory { /* dump data */ uint8_t data[DUMP_BLOCK_SIZE]; } rsp; -}; +} __packed; union as10x_raw_data { /* request */ @@ -446,7 +444,7 @@ union as10x_raw_data { uint8_t data[64 - sizeof(struct as10x_cmd_header_t) /* header */ - 2 /* proc_id */ - 1 /* rc */]; } rsp; -}; +} __packed; struct as10x_cmd_t { struct as10x_cmd_header_t header; @@ -471,15 +469,14 @@ struct as10x_cmd_t { union as10x_dumplog_memory dumplog_memory; union as10x_raw_data raw_data; } body; -}; +} __packed; struct as10x_token_cmd_t { /* token cmd */ struct as10x_cmd_t c; /* token response */ struct as10x_cmd_t r; -}; -#pragma pack() +} __packed; /**************************/ diff --git a/drivers/staging/media/as102/as10x_types.h b/drivers/staging/media/as102/as10x_types.h index 3dedb3c..0b27f3a 100644 --- a/drivers/staging/media/as102/as10x_types.h +++ b/drivers/staging/media/as102/as10x_types.h @@ -111,7 +111,6 @@ #define CFG_MODE_OFF 1 #define CFG_MODE_AUTO 2 -#pragma pack(1) struct as10x_tps { uint8_t constellation; uint8_t hierarchy; @@ -123,7 +122,7 @@ struct as10x_tps { uint8_t DVBH_mask_HP; uint8_t DVBH_mask_LP; uint16_t cell_ID; -}; +} __packed; struct as10x_tune_args { /* frequency */ @@ -144,7 +143,7 @@ struct as10x_tune_args { uint8_t guard_interval; /* transmission mode */ uint8_t transmission_mode; -}; +} __packed; struct as10x_tune_status { /* tune status */ @@ -155,7 +154,7 @@ struct as10x_tune_status { uint16_t PER; /* bit error rate 10^-4 */ uint16_t BER; -}; +} __packed; struct as10x_demod_stats { /* frame counter */ @@ -168,13 +167,13 @@ struct as10x_demod_stats { uint16_t mer; /* statistics calculation state indicator (started or not) */ uint8_t has_started; -}; +} __packed; struct as10x_ts_filter { uint16_t pid; /** valid PID value 0x00 : 0x2000 */ uint8_t type; /** Red TS_PID_TYPE_ values */ uint8_t idx; /** index in filtering table */ -}; +} __packed; struct as10x_register_value { uint8_t mode; @@ -183,9 +182,7 @@ struct as10x_register_value { uint16_t value16; /* 16 bit value */ uint32_t value32; /* 32 bit value */ }u; -}; - -#pragma pack() +} __packed; struct as10x_register_addr { /* register addr */ -- cgit v0.10.2 From 880102898f19cf9f9ba36dc9d838b5476645ce00 Mon Sep 17 00:00:00 2001 From: Sylwester Nawrocki Date: Sun, 6 Nov 2011 16:31:43 -0300 Subject: [media] staging: as102: Fix the dvb device registration error path Release already acquired resources when error happens during devices registration steps. Use dev_err() where struct device is available, instead of driver specific err(). Cc: Devin Heitmueller Signed-off-by: Sylwester Nawrocki Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/staging/media/as102/as102_drv.c b/drivers/staging/media/as102/as102_drv.c index 85f58b9..e775900 100644 --- a/drivers/staging/media/as102/as102_drv.c +++ b/drivers/staging/media/as102/as102_drv.c @@ -195,19 +195,16 @@ static int as102_dvb_dmx_stop_feed(struct dvb_demux_feed *dvbdmxfeed) int as102_dvb_register(struct as102_dev_t *as102_dev) { - int ret = 0; - ENTER(); + struct device *dev = &as102_dev->bus_adap.usb_dev->dev; + int ret; ret = dvb_register_adapter(&as102_dev->dvb_adap, - as102_dev->name, - THIS_MODULE, - &as102_dev->bus_adap.usb_dev->dev, - adapter_nr - ); + as102_dev->name, THIS_MODULE, + dev, adapter_nr); if (ret < 0) { - err("%s: dvb_register_adapter() failed (errno = %d)", - __func__, ret); - goto failed; + dev_err(dev, "%s: dvb_register_adapter() failed: %d\n", + __func__, ret); + return ret; } as102_dev->dvb_dmx.priv = as102_dev; @@ -225,22 +222,22 @@ int as102_dvb_register(struct as102_dev_t *as102_dev) ret = dvb_dmx_init(&as102_dev->dvb_dmx); if (ret < 0) { - err("%s: dvb_dmx_init() failed (errno = %d)", __func__, ret); - goto failed; + dev_err("%s: dvb_dmx_init() failed: %d\n", __func__, ret); + goto edmxinit; } ret = dvb_dmxdev_init(&as102_dev->dvb_dmxdev, &as102_dev->dvb_adap); if (ret < 0) { - err("%s: dvb_dmxdev_init() failed (errno = %d)", __func__, - ret); - goto failed; + dev_err(dev, "%s: dvb_dmxdev_init() failed: %d\n", + __func__, ret); + goto edmxdinit; } ret = as102_dvb_register_fe(as102_dev, &as102_dev->dvb_fe); if (ret < 0) { - err("%s: as102_dvb_register_frontend() failed (errno = %d)", + dev_err(dev, "%s: as102_dvb_register_frontend() failed: %d", __func__, ret); - goto failed; + goto efereg; } /* init bus mutex for token locking */ @@ -256,16 +253,21 @@ int as102_dvb_register(struct as102_dev_t *as102_dev) if (fw_upload) try_then_request_module(as102_fw_upload(&as102_dev->bus_adap), "firmware_class"); -failed: - LEAVE(); - /* FIXME: free dvb_XXX */ + + pr_info("Registered device %s", as102_dev->name); + return 0; + +efereg: + dvb_dmxdev_release(&as102_dev->dvb_dmxdev); +edmxdinit: + dvb_dmx_release(&as102_dev->dvb_dmx); +edmxinit: + dvb_unregister_adapter(&as102_dev->dvb_adap); return ret; } void as102_dvb_unregister(struct as102_dev_t *as102_dev) { - ENTER(); - /* unregister as102 frontend */ as102_dvb_unregister_fe(&as102_dev->dvb_fe); @@ -276,7 +278,7 @@ void as102_dvb_unregister(struct as102_dev_t *as102_dev) /* unregister dvb adapter */ dvb_unregister_adapter(&as102_dev->dvb_adap); - LEAVE(); + pr_info("Unregistered device %s", as102_dev->name); } static int __init as102_driver_init(void) -- cgit v0.10.2 From 14e0e4bf6c8c98ef36542280b3147b4e79e7131b Mon Sep 17 00:00:00 2001 From: Sylwester Nawrocki Date: Sun, 6 Nov 2011 16:31:44 -0300 Subject: [media] staging: as102: Whitespace and indentation cleanup Remove some unnecessary braces. Replace spaces with tabs where expected. Replace gcc specific __FUNCTION__ with C99 __func__. No functional changes. Cc: Devin Heitmueller Signed-off-by: Sylwester Nawrocki Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/staging/media/as102/as102_drv.c b/drivers/staging/media/as102/as102_drv.c index e775900..3234039 100644 --- a/drivers/staging/media/as102/as102_drv.c +++ b/drivers/staging/media/as102/as102_drv.c @@ -121,22 +121,22 @@ static int as10x_pid_filter(struct as102_dev_t *dev, switch (onoff) { case 0: - ret = as10x_cmd_del_PID_filter(bus_adap, (uint16_t) pid); - dprintk(debug, "DEL_PID_FILTER([%02d] 0x%04x) ret = %d\n", - index, pid, ret); - break; + ret = as10x_cmd_del_PID_filter(bus_adap, (uint16_t) pid); + dprintk(debug, "DEL_PID_FILTER([%02d] 0x%04x) ret = %d\n", + index, pid, ret); + break; case 1: { - struct as10x_ts_filter filter; + struct as10x_ts_filter filter; - filter.type = TS_PID_TYPE_TS; - filter.idx = 0xFF; - filter.pid = pid; + filter.type = TS_PID_TYPE_TS; + filter.idx = 0xFF; + filter.pid = pid; - ret = as10x_cmd_add_PID_filter(bus_adap, &filter); - dprintk(debug, "ADD_PID_FILTER([%02d -> %02d], 0x%04x) ret = %d\n", - index, filter.idx, filter.pid, ret); - break; + ret = as10x_cmd_add_PID_filter(bus_adap, &filter); + dprintk(debug, "ADD_PID_FILTER([%02d -> %02d], 0x%04x) ret = %d\n", + index, filter.idx, filter.pid, ret); + break; } } @@ -157,10 +157,9 @@ static int as102_dvb_dmx_start_feed(struct dvb_demux_feed *dvbdmxfeed) if (mutex_lock_interruptible(&as102_dev->sem)) return -ERESTARTSYS; - if (pid_filtering) { - as10x_pid_filter(as102_dev, - dvbdmxfeed->index, dvbdmxfeed->pid, 1); - } + if (pid_filtering) + as10x_pid_filter(as102_dev, dvbdmxfeed->index, + dvbdmxfeed->pid, 1); if (as102_dev->streaming++ == 0) ret = as102_start_stream(as102_dev); @@ -183,10 +182,9 @@ static int as102_dvb_dmx_stop_feed(struct dvb_demux_feed *dvbdmxfeed) if (--as102_dev->streaming == 0) as102_stop_stream(as102_dev); - if (pid_filtering) { - as10x_pid_filter(as102_dev, - dvbdmxfeed->index, dvbdmxfeed->pid, 0); - } + if (pid_filtering) + as10x_pid_filter(as102_dev, dvbdmxfeed->index, + dvbdmxfeed->pid, 0); mutex_unlock(&as102_dev->sem); LEAVE(); diff --git a/drivers/staging/media/as102/as102_drv.h b/drivers/staging/media/as102/as102_drv.h index af2bf1e..d32019c 100644 --- a/drivers/staging/media/as102/as102_drv.h +++ b/drivers/staging/media/as102/as102_drv.h @@ -32,13 +32,13 @@ extern struct usb_driver as102_usb_driver; #define dprintk(debug, args...) \ do { if (debug) { \ - printk(KERN_DEBUG "%s: ",__FUNCTION__); \ + pr_debug("%s: ", __func__); \ printk(args); \ } } while (0) #ifdef TRACE -#define ENTER() printk(">> enter %s\n", __FUNCTION__) -#define LEAVE() printk("<< leave %s\n", __FUNCTION__) +#define ENTER() pr_debug(">> enter %s\n", __func__) +#define LEAVE() pr_debug("<< leave %s\n", __func__) #else #define ENTER() #define LEAVE() diff --git a/drivers/staging/media/as102/as102_usb_drv.c b/drivers/staging/media/as102/as102_usb_drv.c index 0a8f12b..e0c3854 100644 --- a/drivers/staging/media/as102/as102_usb_drv.c +++ b/drivers/staging/media/as102/as102_usb_drv.c @@ -56,16 +56,16 @@ static const char *as102_device_names[] = { }; struct usb_driver as102_usb_driver = { - .name = DRIVER_FULL_NAME, - .probe = as102_usb_probe, - .disconnect = as102_usb_disconnect, - .id_table = as102_usb_id_table + .name = DRIVER_FULL_NAME, + .probe = as102_usb_probe, + .disconnect = as102_usb_disconnect, + .id_table = as102_usb_id_table }; static const struct file_operations as102_dev_fops = { - .owner = THIS_MODULE, - .open = as102_open, - .release = as102_release, + .owner = THIS_MODULE, + .open = as102_open, + .release = as102_release, }; static struct usb_class_driver as102_usb_class_driver = { diff --git a/drivers/staging/media/as102/as10x_cmd.c b/drivers/staging/media/as102/as10x_cmd.c index 0dcba80..1663a45 100644 --- a/drivers/staging/media/as102/as10x_cmd.c +++ b/drivers/staging/media/as102/as10x_cmd.c @@ -232,7 +232,7 @@ out: } /** - * send get TPS command to AS10x + * as10x_cmd_get_tps - send get TPS command to AS10x * @phandle: pointer to AS10x handle * @ptps: pointer to TPS parameters structure * diff --git a/drivers/staging/media/as102/as10x_cmd.h b/drivers/staging/media/as102/as10x_cmd.h index 05f7150..9af8862 100644 --- a/drivers/staging/media/as102/as10x_cmd.h +++ b/drivers/staging/media/as102/as10x_cmd.h @@ -28,422 +28,423 @@ /*********************************/ /* MACRO DEFINITIONS */ /*********************************/ -#define AS10X_CMD_ERROR -1 +#define AS10X_CMD_ERROR -1 -#define SERVICE_PROG_ID 0x0002 -#define SERVICE_PROG_VERSION 0x0001 +#define SERVICE_PROG_ID 0x0002 +#define SERVICE_PROG_VERSION 0x0001 -#define HIER_NONE 0x00 -#define HIER_LOW_PRIORITY 0x01 +#define HIER_NONE 0x00 +#define HIER_LOW_PRIORITY 0x01 #define HEADER_SIZE (sizeof(struct as10x_cmd_header_t)) /* context request types */ -#define GET_CONTEXT_DATA 1 -#define SET_CONTEXT_DATA 2 +#define GET_CONTEXT_DATA 1 +#define SET_CONTEXT_DATA 2 /* ODSP suspend modes */ -#define CFG_MODE_ODSP_RESUME 0 -#define CFG_MODE_ODSP_SUSPEND 1 +#define CFG_MODE_ODSP_RESUME 0 +#define CFG_MODE_ODSP_SUSPEND 1 /* Dump memory size */ -#define DUMP_BLOCK_SIZE_MAX 0x20 +#define DUMP_BLOCK_SIZE_MAX 0x20 /*********************************/ /* TYPE DEFINITION */ /*********************************/ enum control_proc { - CONTROL_PROC_TURNON = 0x0001, - CONTROL_PROC_TURNON_RSP = 0x0100, - CONTROL_PROC_SET_REGISTER = 0x0002, - CONTROL_PROC_SET_REGISTER_RSP = 0x0200, - CONTROL_PROC_GET_REGISTER = 0x0003, - CONTROL_PROC_GET_REGISTER_RSP = 0x0300, - CONTROL_PROC_SETTUNE = 0x000A, - CONTROL_PROC_SETTUNE_RSP = 0x0A00, - CONTROL_PROC_GETTUNESTAT = 0x000B, - CONTROL_PROC_GETTUNESTAT_RSP = 0x0B00, - CONTROL_PROC_GETTPS = 0x000D, - CONTROL_PROC_GETTPS_RSP = 0x0D00, - CONTROL_PROC_SETFILTER = 0x000E, - CONTROL_PROC_SETFILTER_RSP = 0x0E00, - CONTROL_PROC_REMOVEFILTER = 0x000F, - CONTROL_PROC_REMOVEFILTER_RSP = 0x0F00, - CONTROL_PROC_GET_IMPULSE_RESP = 0x0012, - CONTROL_PROC_GET_IMPULSE_RESP_RSP = 0x1200, - CONTROL_PROC_START_STREAMING = 0x0013, - CONTROL_PROC_START_STREAMING_RSP = 0x1300, - CONTROL_PROC_STOP_STREAMING = 0x0014, - CONTROL_PROC_STOP_STREAMING_RSP = 0x1400, - CONTROL_PROC_GET_DEMOD_STATS = 0x0015, - CONTROL_PROC_GET_DEMOD_STATS_RSP = 0x1500, - CONTROL_PROC_ELNA_CHANGE_MODE = 0x0016, - CONTROL_PROC_ELNA_CHANGE_MODE_RSP = 0x1600, - CONTROL_PROC_ODSP_CHANGE_MODE = 0x0017, - CONTROL_PROC_ODSP_CHANGE_MODE_RSP = 0x1700, - CONTROL_PROC_AGC_CHANGE_MODE = 0x0018, - CONTROL_PROC_AGC_CHANGE_MODE_RSP = 0x1800, - - CONTROL_PROC_CONTEXT = 0x00FC, - CONTROL_PROC_CONTEXT_RSP = 0xFC00, - CONTROL_PROC_DUMP_MEMORY = 0x00FD, - CONTROL_PROC_DUMP_MEMORY_RSP = 0xFD00, - CONTROL_PROC_DUMPLOG_MEMORY = 0x00FE, - CONTROL_PROC_DUMPLOG_MEMORY_RSP = 0xFE00, - CONTROL_PROC_TURNOFF = 0x00FF, - CONTROL_PROC_TURNOFF_RSP = 0xFF00 + CONTROL_PROC_TURNON = 0x0001, + CONTROL_PROC_TURNON_RSP = 0x0100, + CONTROL_PROC_SET_REGISTER = 0x0002, + CONTROL_PROC_SET_REGISTER_RSP = 0x0200, + CONTROL_PROC_GET_REGISTER = 0x0003, + CONTROL_PROC_GET_REGISTER_RSP = 0x0300, + CONTROL_PROC_SETTUNE = 0x000A, + CONTROL_PROC_SETTUNE_RSP = 0x0A00, + CONTROL_PROC_GETTUNESTAT = 0x000B, + CONTROL_PROC_GETTUNESTAT_RSP = 0x0B00, + CONTROL_PROC_GETTPS = 0x000D, + CONTROL_PROC_GETTPS_RSP = 0x0D00, + CONTROL_PROC_SETFILTER = 0x000E, + CONTROL_PROC_SETFILTER_RSP = 0x0E00, + CONTROL_PROC_REMOVEFILTER = 0x000F, + CONTROL_PROC_REMOVEFILTER_RSP = 0x0F00, + CONTROL_PROC_GET_IMPULSE_RESP = 0x0012, + CONTROL_PROC_GET_IMPULSE_RESP_RSP = 0x1200, + CONTROL_PROC_START_STREAMING = 0x0013, + CONTROL_PROC_START_STREAMING_RSP = 0x1300, + CONTROL_PROC_STOP_STREAMING = 0x0014, + CONTROL_PROC_STOP_STREAMING_RSP = 0x1400, + CONTROL_PROC_GET_DEMOD_STATS = 0x0015, + CONTROL_PROC_GET_DEMOD_STATS_RSP = 0x1500, + CONTROL_PROC_ELNA_CHANGE_MODE = 0x0016, + CONTROL_PROC_ELNA_CHANGE_MODE_RSP = 0x1600, + CONTROL_PROC_ODSP_CHANGE_MODE = 0x0017, + CONTROL_PROC_ODSP_CHANGE_MODE_RSP = 0x1700, + CONTROL_PROC_AGC_CHANGE_MODE = 0x0018, + CONTROL_PROC_AGC_CHANGE_MODE_RSP = 0x1800, + + CONTROL_PROC_CONTEXT = 0x00FC, + CONTROL_PROC_CONTEXT_RSP = 0xFC00, + CONTROL_PROC_DUMP_MEMORY = 0x00FD, + CONTROL_PROC_DUMP_MEMORY_RSP = 0xFD00, + CONTROL_PROC_DUMPLOG_MEMORY = 0x00FE, + CONTROL_PROC_DUMPLOG_MEMORY_RSP = 0xFE00, + CONTROL_PROC_TURNOFF = 0x00FF, + CONTROL_PROC_TURNOFF_RSP = 0xFF00 }; union as10x_turn_on { - /* request */ - struct { - /* request identifier */ - uint16_t proc_id; - } req; - /* response */ - struct { - /* response identifier */ - uint16_t proc_id; - /* error */ - uint8_t error; - } rsp; + /* request */ + struct { + /* request identifier */ + uint16_t proc_id; + } req; + /* response */ + struct { + /* response identifier */ + uint16_t proc_id; + /* error */ + uint8_t error; + } rsp; } __packed; union as10x_turn_off { - /* request */ - struct { - /* request identifier */ - uint16_t proc_id; - } req; - /* response */ - struct { - /* response identifier */ - uint16_t proc_id; - /* error */ - uint8_t err; - } rsp; + /* request */ + struct { + /* request identifier */ + uint16_t proc_id; + } req; + /* response */ + struct { + /* response identifier */ + uint16_t proc_id; + /* error */ + uint8_t err; + } rsp; } __packed; union as10x_set_tune { - /* request */ - struct { - /* request identifier */ - uint16_t proc_id; - /* tune params */ - struct as10x_tune_args args; - } req; - /* response */ - struct { - /* response identifier */ - uint16_t proc_id; - /* response error */ - uint8_t error; - } rsp; + /* request */ + struct { + /* request identifier */ + uint16_t proc_id; + /* tune params */ + struct as10x_tune_args args; + } req; + /* response */ + struct { + /* response identifier */ + uint16_t proc_id; + /* response error */ + uint8_t error; + } rsp; } __packed; union as10x_get_tune_status { - /* request */ - struct { - /* request identifier */ - uint16_t proc_id; - } req; - /* response */ - struct { - /* response identifier */ - uint16_t proc_id; - /* response error */ - uint8_t error; - /* tune status */ - struct as10x_tune_status sts; - } rsp; + /* request */ + struct { + /* request identifier */ + uint16_t proc_id; + } req; + /* response */ + struct { + /* response identifier */ + uint16_t proc_id; + /* response error */ + uint8_t error; + /* tune status */ + struct as10x_tune_status sts; + } rsp; } __packed; union as10x_get_tps { - /* request */ - struct { - /* request identifier */ - uint16_t proc_id; - } req; - /* response */ - struct { - /* response identifier */ - uint16_t proc_id; - /* response error */ - uint8_t error; - /* tps details */ - struct as10x_tps tps; - } rsp; + /* request */ + struct { + /* request identifier */ + uint16_t proc_id; + } req; + /* response */ + struct { + /* response identifier */ + uint16_t proc_id; + /* response error */ + uint8_t error; + /* tps details */ + struct as10x_tps tps; + } rsp; } __packed; union as10x_common { - /* request */ - struct { - /* request identifier */ - uint16_t proc_id; - } req; - /* response */ - struct { - /* response identifier */ - uint16_t proc_id; - /* response error */ - uint8_t error; - } rsp; + /* request */ + struct { + /* request identifier */ + uint16_t proc_id; + } req; + /* response */ + struct { + /* response identifier */ + uint16_t proc_id; + /* response error */ + uint8_t error; + } rsp; } __packed; union as10x_add_pid_filter { - /* request */ - struct { - /* request identifier */ - uint16_t proc_id; - /* PID to filter */ - uint16_t pid; - /* stream type (MPE, PSI/SI or PES )*/ - uint8_t stream_type; - /* PID index in filter table */ - uint8_t idx; - } req; - /* response */ - struct { - /* response identifier */ - uint16_t proc_id; - /* response error */ - uint8_t error; - /* Filter id */ - uint8_t filter_id; - } rsp; + /* request */ + struct { + /* request identifier */ + uint16_t proc_id; + /* PID to filter */ + uint16_t pid; + /* stream type (MPE, PSI/SI or PES )*/ + uint8_t stream_type; + /* PID index in filter table */ + uint8_t idx; + } req; + /* response */ + struct { + /* response identifier */ + uint16_t proc_id; + /* response error */ + uint8_t error; + /* Filter id */ + uint8_t filter_id; + } rsp; } __packed; union as10x_del_pid_filter { - /* request */ - struct { - /* request identifier */ - uint16_t proc_id; - /* PID to remove */ - uint16_t pid; - } req; - /* response */ - struct { - /* response identifier */ - uint16_t proc_id; - /* response error */ - uint8_t error; - } rsp; + /* request */ + struct { + /* request identifier */ + uint16_t proc_id; + /* PID to remove */ + uint16_t pid; + } req; + /* response */ + struct { + /* response identifier */ + uint16_t proc_id; + /* response error */ + uint8_t error; + } rsp; } __packed; union as10x_start_streaming { - /* request */ - struct { - /* request identifier */ - uint16_t proc_id; - } req; - /* response */ - struct { - /* response identifier */ - uint16_t proc_id; - /* error */ - uint8_t error; - } rsp; + /* request */ + struct { + /* request identifier */ + uint16_t proc_id; + } req; + /* response */ + struct { + /* response identifier */ + uint16_t proc_id; + /* error */ + uint8_t error; + } rsp; } __packed; union as10x_stop_streaming { - /* request */ - struct { - /* request identifier */ - uint16_t proc_id; - } req; - /* response */ - struct { - /* response identifier */ - uint16_t proc_id; - /* error */ - uint8_t error; - } rsp; + /* request */ + struct { + /* request identifier */ + uint16_t proc_id; + } req; + /* response */ + struct { + /* response identifier */ + uint16_t proc_id; + /* error */ + uint8_t error; + } rsp; } __packed; union as10x_get_demod_stats { - /* request */ - struct { - /* request identifier */ - uint16_t proc_id; - } req; - /* response */ - struct { - /* response identifier */ - uint16_t proc_id; - /* error */ - uint8_t error; - /* demod stats */ - struct as10x_demod_stats stats; - } rsp; + /* request */ + struct { + /* request identifier */ + uint16_t proc_id; + } req; + /* response */ + struct { + /* response identifier */ + uint16_t proc_id; + /* error */ + uint8_t error; + /* demod stats */ + struct as10x_demod_stats stats; + } rsp; } __packed; union as10x_get_impulse_resp { - /* request */ - struct { - /* request identifier */ - uint16_t proc_id; - } req; - /* response */ - struct { - /* response identifier */ - uint16_t proc_id; - /* error */ - uint8_t error; - /* impulse response ready */ - uint8_t is_ready; - } rsp; + /* request */ + struct { + /* request identifier */ + uint16_t proc_id; + } req; + /* response */ + struct { + /* response identifier */ + uint16_t proc_id; + /* error */ + uint8_t error; + /* impulse response ready */ + uint8_t is_ready; + } rsp; } __packed; union as10x_fw_context { - /* request */ - struct { - /* request identifier */ - uint16_t proc_id; - /* value to write (for set context)*/ - struct as10x_register_value reg_val; - /* context tag */ - uint16_t tag; - /* context request type */ - uint16_t type; - } req; - /* response */ - struct { - /* response identifier */ - uint16_t proc_id; - /* value read (for get context) */ - struct as10x_register_value reg_val; - /* context request type */ - uint16_t type; - /* error */ - uint8_t error; - } rsp; + /* request */ + struct { + /* request identifier */ + uint16_t proc_id; + /* value to write (for set context)*/ + struct as10x_register_value reg_val; + /* context tag */ + uint16_t tag; + /* context request type */ + uint16_t type; + } req; + /* response */ + struct { + /* response identifier */ + uint16_t proc_id; + /* value read (for get context) */ + struct as10x_register_value reg_val; + /* context request type */ + uint16_t type; + /* error */ + uint8_t error; + } rsp; } __packed; union as10x_set_register { - /* request */ - struct { - /* response identifier */ - uint16_t proc_id; - /* register description */ - struct as10x_register_addr reg_addr; - /* register content */ - struct as10x_register_value reg_val; - } req; - /* response */ - struct { - /* response identifier */ - uint16_t proc_id; - /* error */ - uint8_t error; - } rsp; + /* request */ + struct { + /* response identifier */ + uint16_t proc_id; + /* register description */ + struct as10x_register_addr reg_addr; + /* register content */ + struct as10x_register_value reg_val; + } req; + /* response */ + struct { + /* response identifier */ + uint16_t proc_id; + /* error */ + uint8_t error; + } rsp; } __packed; union as10x_get_register { - /* request */ - struct { - /* response identifier */ - uint16_t proc_id; - /* register description */ - struct as10x_register_addr reg_addr; - } req; - /* response */ - struct { - /* response identifier */ - uint16_t proc_id; - /* error */ - uint8_t error; - /* register content */ - struct as10x_register_value reg_val; - } rsp; + /* request */ + struct { + /* response identifier */ + uint16_t proc_id; + /* register description */ + struct as10x_register_addr reg_addr; + } req; + /* response */ + struct { + /* response identifier */ + uint16_t proc_id; + /* error */ + uint8_t error; + /* register content */ + struct as10x_register_value reg_val; + } rsp; } __packed; union as10x_cfg_change_mode { - /* request */ - struct { - /* request identifier */ - uint16_t proc_id; - /* mode */ - uint8_t mode; - } req; - /* response */ - struct { - /* response identifier */ - uint16_t proc_id; - /* error */ - uint8_t error; - } rsp; + /* request */ + struct { + /* request identifier */ + uint16_t proc_id; + /* mode */ + uint8_t mode; + } req; + /* response */ + struct { + /* response identifier */ + uint16_t proc_id; + /* error */ + uint8_t error; + } rsp; } __packed; struct as10x_cmd_header_t { - uint16_t req_id; - uint16_t prog; - uint16_t version; - uint16_t data_len; + uint16_t req_id; + uint16_t prog; + uint16_t version; + uint16_t data_len; } __packed; #define DUMP_BLOCK_SIZE 16 union as10x_dump_memory { - /* request */ - struct { - /* request identifier */ - uint16_t proc_id; - /* dump memory type request */ - uint8_t dump_req; - /* register description */ - struct as10x_register_addr reg_addr; - /* nb blocks to read */ - uint16_t num_blocks; - } req; - /* response */ - struct { - /* response identifier */ - uint16_t proc_id; - /* error */ - uint8_t error; - /* dump response */ - uint8_t dump_rsp; - /* data */ - union { - uint8_t data8[DUMP_BLOCK_SIZE]; - uint16_t data16[DUMP_BLOCK_SIZE / sizeof(uint16_t)]; - uint32_t data32[DUMP_BLOCK_SIZE / sizeof(uint32_t)]; - } u; - } rsp; + /* request */ + struct { + /* request identifier */ + uint16_t proc_id; + /* dump memory type request */ + uint8_t dump_req; + /* register description */ + struct as10x_register_addr reg_addr; + /* nb blocks to read */ + uint16_t num_blocks; + } req; + /* response */ + struct { + /* response identifier */ + uint16_t proc_id; + /* error */ + uint8_t error; + /* dump response */ + uint8_t dump_rsp; + /* data */ + union { + uint8_t data8[DUMP_BLOCK_SIZE]; + uint16_t data16[DUMP_BLOCK_SIZE / sizeof(uint16_t)]; + uint32_t data32[DUMP_BLOCK_SIZE / sizeof(uint32_t)]; + } u; + } rsp; } __packed; union as10x_dumplog_memory { - struct { - /* request identifier */ - uint16_t proc_id; - /* dump memory type request */ - uint8_t dump_req; - } req; - struct { - /* request identifier */ - uint16_t proc_id; - /* error */ - uint8_t error; - /* dump response */ - uint8_t dump_rsp; - /* dump data */ - uint8_t data[DUMP_BLOCK_SIZE]; - } rsp; + struct { + /* request identifier */ + uint16_t proc_id; + /* dump memory type request */ + uint8_t dump_req; + } req; + struct { + /* request identifier */ + uint16_t proc_id; + /* error */ + uint8_t error; + /* dump response */ + uint8_t dump_rsp; + /* dump data */ + uint8_t data[DUMP_BLOCK_SIZE]; + } rsp; } __packed; union as10x_raw_data { - /* request */ - struct { - uint16_t proc_id; - uint8_t data[64 - sizeof(struct as10x_cmd_header_t) -2 /* proc_id */]; - } req; - /* response */ - struct { - uint16_t proc_id; - uint8_t error; - uint8_t data[64 - sizeof(struct as10x_cmd_header_t) /* header */ - - 2 /* proc_id */ - 1 /* rc */]; - } rsp; + /* request */ + struct { + uint16_t proc_id; + uint8_t data[64 - sizeof(struct as10x_cmd_header_t) + - 2 /* proc_id */]; + } req; + /* response */ + struct { + uint16_t proc_id; + uint8_t error; + uint8_t data[64 - sizeof(struct as10x_cmd_header_t) + - 2 /* proc_id */ - 1 /* rc */]; + } rsp; } __packed; struct as10x_cmd_t { @@ -472,10 +473,10 @@ struct as10x_cmd_t { } __packed; struct as10x_token_cmd_t { - /* token cmd */ - struct as10x_cmd_t c; - /* token response */ - struct as10x_cmd_t r; + /* token cmd */ + struct as10x_cmd_t c; + /* token response */ + struct as10x_cmd_t r; } __packed; diff --git a/drivers/staging/media/as102/as10x_handle.h b/drivers/staging/media/as102/as10x_handle.h index 4f01a76..d67203a 100644 --- a/drivers/staging/media/as102/as10x_handle.h +++ b/drivers/staging/media/as102/as10x_handle.h @@ -24,9 +24,9 @@ struct as102_dev_t; #include "as10x_cmd.h" /* values for "mode" field */ -#define REGMODE8 8 -#define REGMODE16 16 -#define REGMODE32 32 +#define REGMODE8 8 +#define REGMODE16 16 +#define REGMODE32 32 struct as102_priv_ops_t { int (*upload_fw_pkt) (struct as102_bus_adapter_t *bus_adap, diff --git a/drivers/staging/media/as102/as10x_types.h b/drivers/staging/media/as102/as10x_types.h index 0b27f3a..c40c812 100644 --- a/drivers/staging/media/as102/as10x_types.h +++ b/drivers/staging/media/as102/as10x_types.h @@ -26,170 +26,169 @@ /*********************************/ /* bandwidth constant values */ -#define BW_5_MHZ 0x00 -#define BW_6_MHZ 0x01 -#define BW_7_MHZ 0x02 -#define BW_8_MHZ 0x03 +#define BW_5_MHZ 0x00 +#define BW_6_MHZ 0x01 +#define BW_7_MHZ 0x02 +#define BW_8_MHZ 0x03 /* hierarchy priority selection values */ -#define HIER_NO_PRIORITY 0x00 -#define HIER_LOW_PRIORITY 0x01 -#define HIER_HIGH_PRIORITY 0x02 +#define HIER_NO_PRIORITY 0x00 +#define HIER_LOW_PRIORITY 0x01 +#define HIER_HIGH_PRIORITY 0x02 /* constellation available values */ -#define CONST_QPSK 0x00 -#define CONST_QAM16 0x01 -#define CONST_QAM64 0x02 -#define CONST_UNKNOWN 0xFF +#define CONST_QPSK 0x00 +#define CONST_QAM16 0x01 +#define CONST_QAM64 0x02 +#define CONST_UNKNOWN 0xFF /* hierarchy available values */ -#define HIER_NONE 0x00 -#define HIER_ALPHA_1 0x01 -#define HIER_ALPHA_2 0x02 -#define HIER_ALPHA_4 0x03 -#define HIER_UNKNOWN 0xFF +#define HIER_NONE 0x00 +#define HIER_ALPHA_1 0x01 +#define HIER_ALPHA_2 0x02 +#define HIER_ALPHA_4 0x03 +#define HIER_UNKNOWN 0xFF /* interleaving available values */ -#define INTLV_NATIVE 0x00 -#define INTLV_IN_DEPTH 0x01 -#define INTLV_UNKNOWN 0xFF +#define INTLV_NATIVE 0x00 +#define INTLV_IN_DEPTH 0x01 +#define INTLV_UNKNOWN 0xFF /* code rate available values */ -#define CODE_RATE_1_2 0x00 -#define CODE_RATE_2_3 0x01 -#define CODE_RATE_3_4 0x02 -#define CODE_RATE_5_6 0x03 -#define CODE_RATE_7_8 0x04 -#define CODE_RATE_UNKNOWN 0xFF +#define CODE_RATE_1_2 0x00 +#define CODE_RATE_2_3 0x01 +#define CODE_RATE_3_4 0x02 +#define CODE_RATE_5_6 0x03 +#define CODE_RATE_7_8 0x04 +#define CODE_RATE_UNKNOWN 0xFF /* guard interval available values */ -#define GUARD_INT_1_32 0x00 -#define GUARD_INT_1_16 0x01 -#define GUARD_INT_1_8 0x02 -#define GUARD_INT_1_4 0x03 -#define GUARD_UNKNOWN 0xFF +#define GUARD_INT_1_32 0x00 +#define GUARD_INT_1_16 0x01 +#define GUARD_INT_1_8 0x02 +#define GUARD_INT_1_4 0x03 +#define GUARD_UNKNOWN 0xFF /* transmission mode available values */ -#define TRANS_MODE_2K 0x00 -#define TRANS_MODE_8K 0x01 -#define TRANS_MODE_4K 0x02 -#define TRANS_MODE_UNKNOWN 0xFF +#define TRANS_MODE_2K 0x00 +#define TRANS_MODE_8K 0x01 +#define TRANS_MODE_4K 0x02 +#define TRANS_MODE_UNKNOWN 0xFF /* DVBH signalling available values */ -#define TIMESLICING_PRESENT 0x01 -#define MPE_FEC_PRESENT 0x02 +#define TIMESLICING_PRESENT 0x01 +#define MPE_FEC_PRESENT 0x02 /* tune state available */ -#define TUNE_STATUS_NOT_TUNED 0x00 -#define TUNE_STATUS_IDLE 0x01 -#define TUNE_STATUS_LOCKING 0x02 -#define TUNE_STATUS_SIGNAL_DVB_OK 0x03 -#define TUNE_STATUS_STREAM_DETECTED 0x04 -#define TUNE_STATUS_STREAM_TUNED 0x05 -#define TUNE_STATUS_ERROR 0xFF +#define TUNE_STATUS_NOT_TUNED 0x00 +#define TUNE_STATUS_IDLE 0x01 +#define TUNE_STATUS_LOCKING 0x02 +#define TUNE_STATUS_SIGNAL_DVB_OK 0x03 +#define TUNE_STATUS_STREAM_DETECTED 0x04 +#define TUNE_STATUS_STREAM_TUNED 0x05 +#define TUNE_STATUS_ERROR 0xFF /* available TS FID filter types */ -#define TS_PID_TYPE_TS 0 -#define TS_PID_TYPE_PSI_SI 1 -#define TS_PID_TYPE_MPE 2 +#define TS_PID_TYPE_TS 0 +#define TS_PID_TYPE_PSI_SI 1 +#define TS_PID_TYPE_MPE 2 /* number of echos available */ -#define MAX_ECHOS 15 +#define MAX_ECHOS 15 /* Context types */ -#define CONTEXT_LNA 1010 -#define CONTEXT_ELNA_HYSTERESIS 4003 -#define CONTEXT_ELNA_GAIN 4004 -#define CONTEXT_MER_THRESHOLD 5005 -#define CONTEXT_MER_OFFSET 5006 -#define CONTEXT_IR_STATE 7000 -#define CONTEXT_TSOUT_MSB_FIRST 7004 -#define CONTEXT_TSOUT_FALLING_EDGE 7005 +#define CONTEXT_LNA 1010 +#define CONTEXT_ELNA_HYSTERESIS 4003 +#define CONTEXT_ELNA_GAIN 4004 +#define CONTEXT_MER_THRESHOLD 5005 +#define CONTEXT_MER_OFFSET 5006 +#define CONTEXT_IR_STATE 7000 +#define CONTEXT_TSOUT_MSB_FIRST 7004 +#define CONTEXT_TSOUT_FALLING_EDGE 7005 /* Configuration modes */ -#define CFG_MODE_ON 0 -#define CFG_MODE_OFF 1 -#define CFG_MODE_AUTO 2 +#define CFG_MODE_ON 0 +#define CFG_MODE_OFF 1 +#define CFG_MODE_AUTO 2 struct as10x_tps { - uint8_t constellation; - uint8_t hierarchy; - uint8_t interleaving_mode; - uint8_t code_rate_HP; - uint8_t code_rate_LP; - uint8_t guard_interval; - uint8_t transmission_mode; - uint8_t DVBH_mask_HP; - uint8_t DVBH_mask_LP; - uint16_t cell_ID; + uint8_t constellation; + uint8_t hierarchy; + uint8_t interleaving_mode; + uint8_t code_rate_HP; + uint8_t code_rate_LP; + uint8_t guard_interval; + uint8_t transmission_mode; + uint8_t DVBH_mask_HP; + uint8_t DVBH_mask_LP; + uint16_t cell_ID; } __packed; struct as10x_tune_args { - /* frequency */ - uint32_t freq; - /* bandwidth */ - uint8_t bandwidth; - /* hierarchy selection */ - uint8_t hier_select; - /* constellation */ - uint8_t constellation; - /* hierarchy */ - uint8_t hierarchy; - /* interleaving mode */ - uint8_t interleaving_mode; - /* code rate */ - uint8_t code_rate; - /* guard interval */ - uint8_t guard_interval; - /* transmission mode */ - uint8_t transmission_mode; + /* frequency */ + uint32_t freq; + /* bandwidth */ + uint8_t bandwidth; + /* hierarchy selection */ + uint8_t hier_select; + /* constellation */ + uint8_t constellation; + /* hierarchy */ + uint8_t hierarchy; + /* interleaving mode */ + uint8_t interleaving_mode; + /* code rate */ + uint8_t code_rate; + /* guard interval */ + uint8_t guard_interval; + /* transmission mode */ + uint8_t transmission_mode; } __packed; struct as10x_tune_status { - /* tune status */ - uint8_t tune_state; - /* signal strength */ - int16_t signal_strength; - /* packet error rate 10^-4 */ - uint16_t PER; - /* bit error rate 10^-4 */ - uint16_t BER; + /* tune status */ + uint8_t tune_state; + /* signal strength */ + int16_t signal_strength; + /* packet error rate 10^-4 */ + uint16_t PER; + /* bit error rate 10^-4 */ + uint16_t BER; } __packed; struct as10x_demod_stats { - /* frame counter */ - uint32_t frame_count; - /* Bad frame counter */ - uint32_t bad_frame_count; - /* Number of wrong bytes fixed by Reed-Solomon */ - uint32_t bytes_fixed_by_rs; - /* Averaged MER */ - uint16_t mer; - /* statistics calculation state indicator (started or not) */ - uint8_t has_started; + /* frame counter */ + uint32_t frame_count; + /* Bad frame counter */ + uint32_t bad_frame_count; + /* Number of wrong bytes fixed by Reed-Solomon */ + uint32_t bytes_fixed_by_rs; + /* Averaged MER */ + uint16_t mer; + /* statistics calculation state indicator (started or not) */ + uint8_t has_started; } __packed; struct as10x_ts_filter { - uint16_t pid; /** valid PID value 0x00 : 0x2000 */ - uint8_t type; /** Red TS_PID_TYPE_ values */ - uint8_t idx; /** index in filtering table */ + uint16_t pid; /* valid PID value 0x00 : 0x2000 */ + uint8_t type; /* Red TS_PID_TYPE_ values */ + uint8_t idx; /* index in filtering table */ } __packed; struct as10x_register_value { - uint8_t mode; - union { - uint8_t value8; /* 8 bit value */ - uint16_t value16; /* 16 bit value */ - uint32_t value32; /* 32 bit value */ - }u; + uint8_t mode; + union { + uint8_t value8; /* 8 bit value */ + uint16_t value16; /* 16 bit value */ + uint32_t value32; /* 32 bit value */ + } u; } __packed; struct as10x_register_addr { - /* register addr */ - uint32_t addr; - /* register mode access */ - uint8_t mode; + /* register addr */ + uint32_t addr; + /* register mode access */ + uint8_t mode; }; - #endif -- cgit v0.10.2 From 7d462fe580d6b73f0307588b898b2e6c8ad45d41 Mon Sep 17 00:00:00 2001 From: Sylwester Nawrocki Date: Sun, 6 Nov 2011 16:31:45 -0300 Subject: [media] staging: as102: Replace printk(KERN_ witk pr_ While at it also correct some spelling errors. Cc: Devin Heitmueller Signed-off-by: Sylwester Nawrocki Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/staging/media/as102/as102_fw.c b/drivers/staging/media/as102/as102_fw.c index ab7dcdb..fa56939 100644 --- a/drivers/staging/media/as102/as102_fw.c +++ b/drivers/staging/media/as102/as102_fw.c @@ -58,7 +58,7 @@ static int parse_hex_line(unsigned char *fw_data, unsigned char *addr, unsigned char *src, dst; if (*fw_data++ != ':') { - printk(KERN_ERR "invalid firmware file\n"); + pr_err("invalid firmware file\n"); return -EFAULT; } @@ -191,21 +191,21 @@ int as102_fw_upload(struct as102_bus_adapter_t *bus_adap) /* request kernel to locate firmware file: part1 */ errno = request_firmware(&firmware, fw1, &dev->dev); if (errno < 0) { - printk(KERN_ERR "%s: unable to locate firmware file: %s\n", - DRIVER_NAME, fw1); + pr_err("%s: unable to locate firmware file: %s\n", + DRIVER_NAME, fw1); goto error; } /* initiate firmware upload */ errno = as102_firmware_upload(bus_adap, cmd_buf, firmware); if (errno < 0) { - printk(KERN_ERR "%s: error during firmware upload part1\n", - DRIVER_NAME); + pr_err("%s: error during firmware upload part1\n", + DRIVER_NAME); goto error; } - printk(KERN_INFO "%s: fimrware: %s loaded with success\n", - DRIVER_NAME, fw1); + pr_info("%s: firmware: %s loaded with success\n", + DRIVER_NAME, fw1); release_firmware(firmware); /* wait for boot to complete */ @@ -214,21 +214,21 @@ int as102_fw_upload(struct as102_bus_adapter_t *bus_adap) /* request kernel to locate firmware file: part2 */ errno = request_firmware(&firmware, fw2, &dev->dev); if (errno < 0) { - printk(KERN_ERR "%s: unable to locate firmware file: %s\n", - DRIVER_NAME, fw2); + pr_err("%s: unable to locate firmware file: %s\n", + DRIVER_NAME, fw2); goto error; } /* initiate firmware upload */ errno = as102_firmware_upload(bus_adap, cmd_buf, firmware); if (errno < 0) { - printk(KERN_ERR "%s: error during firmware upload part2\n", - DRIVER_NAME); + pr_err("%s: error during firmware upload part2\n", + DRIVER_NAME); goto error; } - printk(KERN_INFO "%s: fimrware: %s loaded with success\n", - DRIVER_NAME, fw2); + pr_info("%s: firmware: %s loaded with success\n", + DRIVER_NAME, fw2); error: /* free data buffer */ kfree(cmd_buf); diff --git a/drivers/staging/media/as102/as102_usb_drv.c b/drivers/staging/media/as102/as102_usb_drv.c index e0c3854..3ded7d6 100644 --- a/drivers/staging/media/as102/as102_usb_drv.c +++ b/drivers/staging/media/as102/as102_usb_drv.c @@ -337,7 +337,7 @@ static void as102_usb_disconnect(struct usb_interface *intf) /* decrement usage counter */ kref_put(&as102_dev->kref, as102_usb_release); - printk(KERN_INFO "%s: device has been disconnected\n", DRIVER_NAME); + pr_info("%s: device has been disconnected\n", DRIVER_NAME); LEAVE(); } @@ -360,7 +360,7 @@ static int as102_usb_probe(struct usb_interface *intf, /* This should never actually happen */ if ((sizeof(as102_usb_id_table) / sizeof(struct usb_device_id)) != (sizeof(as102_device_names) / sizeof(const char *))) { - printk(KERN_ERR "Device names table invalid size"); + pr_err("Device names table invalid size"); return -EINVAL; } @@ -399,7 +399,7 @@ static int as102_usb_probe(struct usb_interface *intf, goto failed; } - printk(KERN_INFO "%s: device has been detected\n", DRIVER_NAME); + pr_info("%s: device has been detected\n", DRIVER_NAME); /* request buffer allocation for streaming */ ret = as102_alloc_usb_stream_buffer(as102_dev); @@ -432,8 +432,8 @@ static int as102_open(struct inode *inode, struct file *file) /* fetch device from usb interface */ intf = usb_find_interface(&as102_usb_driver, minor); if (intf == NULL) { - printk(KERN_ERR "%s: can't find device for minor %d\n", - __func__, minor); + pr_err("%s: can't find device for minor %d\n", + __func__, minor); ret = -ENODEV; goto exit; } -- cgit v0.10.2 From c20ec0354f89d402c68d657d94ec3a96c82dcfb5 Mon Sep 17 00:00:00 2001 From: Sylwester Nawrocki Date: Sun, 6 Nov 2011 16:31:46 -0300 Subject: [media] staging: as102: Remove linkage specifiers for C++ The as10x_cmd.h header is not public so there should be no need for an "extern "C"" in it. Cc: Devin Heitmueller Signed-off-by: Sylwester Nawrocki Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/staging/media/as102/as10x_cmd.h b/drivers/staging/media/as102/as10x_cmd.h index 9af8862..da31c6d 100644 --- a/drivers/staging/media/as102/as10x_cmd.h +++ b/drivers/staging/media/as102/as10x_cmd.h @@ -488,10 +488,6 @@ void as10x_cmd_build(struct as10x_cmd_t *pcmd, uint16_t proc_id, uint16_t cmd_len); int as10x_rsp_parse(struct as10x_cmd_t *r, uint16_t proc_id); -#ifdef __cplusplus -extern "C" { -#endif - /* as10x cmd */ int as10x_cmd_turn_on(as10x_handle_t *phandle); int as10x_cmd_turn_off(as10x_handle_t *phandle); @@ -530,7 +526,4 @@ int as10x_cmd_get_context(as10x_handle_t *phandle, int as10x_cmd_eLNA_change_mode(as10x_handle_t *phandle, uint8_t mode); int as10x_context_rsp_parse(struct as10x_cmd_t *prsp, uint16_t proc_id); -#ifdef __cplusplus -} -#endif #endif -- cgit v0.10.2 From 3288e201a1308051b9c8ee858437ab9ef3bcac41 Mon Sep 17 00:00:00 2001 From: Sylwester Nawrocki Date: Sun, 6 Nov 2011 16:31:47 -0300 Subject: [media] staging: as102: Use linux/uaccess.h instead of asm/uaccess.h Cc: Devin Heitmueller Signed-off-by: Sylwester Nawrocki Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/staging/media/as102/as102_drv.c b/drivers/staging/media/as102/as102_drv.c index 3234039..44f6017 100644 --- a/drivers/staging/media/as102/as102_drv.c +++ b/drivers/staging/media/as102/as102_drv.c @@ -24,7 +24,7 @@ #include #include #include -#include +#include #include /* header file for Usb device driver*/ -- cgit v0.10.2 From a11726349c4a5add63a9d51c0e8079e0e9f20624 Mon Sep 17 00:00:00 2001 From: Sylwester Nawrocki Date: Sun, 6 Nov 2011 16:31:48 -0300 Subject: [media] staging: as102: Move variable declarations to the header Fixes following checkpatch.pl warning: WARNING: externs should be avoided in .c files Cc: Devin Heitmueller Signed-off-by: Sylwester Nawrocki Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/staging/media/as102/as102_drv.h b/drivers/staging/media/as102/as102_drv.h index d32019c..06466fd 100644 --- a/drivers/staging/media/as102/as102_drv.h +++ b/drivers/staging/media/as102/as102_drv.h @@ -29,6 +29,7 @@ extern int debug; extern struct usb_driver as102_usb_driver; +extern int elna_enable; #define dprintk(debug, args...) \ do { if (debug) { \ diff --git a/drivers/staging/media/as102/as102_fe.c b/drivers/staging/media/as102/as102_fe.c index 7d7dd55..c2adfe5 100644 --- a/drivers/staging/media/as102/as102_fe.c +++ b/drivers/staging/media/as102/as102_fe.c @@ -23,8 +23,6 @@ #include "as10x_types.h" #include "as10x_cmd.h" -extern int elna_enable; - static void as10x_fe_copy_tps_parameters(struct dvb_frontend_parameters *dst, struct as10x_tps *src); -- cgit v0.10.2 From d758b9ef7aacb66d99529b6a24dc54e9d11434b7 Mon Sep 17 00:00:00 2001 From: Sylwester Nawrocki Date: Sun, 6 Nov 2011 16:31:49 -0300 Subject: [media] staging: as102: Define device name string pointers constant Supresses following checkpatch warning: WARNING: static const char * array should probably be static const char * const Cc: Devin Heitmueller Signed-off-by: Sylwester Nawrocki Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/staging/media/as102/as102_usb_drv.c b/drivers/staging/media/as102/as102_usb_drv.c index 3ded7d6..97bceeb 100644 --- a/drivers/staging/media/as102/as102_usb_drv.c +++ b/drivers/staging/media/as102/as102_usb_drv.c @@ -47,7 +47,7 @@ static struct usb_device_id as102_usb_id_table[] = { /* Note that this table must always have the same number of entries as the as102_usb_id_table struct */ -static const char *as102_device_names[] = { +static const char * const as102_device_names[] = { AS102_REFERENCE_DESIGN, AS102_PCTV_74E, AS102_ELGATO_EYETV_DTT_NAME, -- cgit v0.10.2 From 34490a0a3dfd9c048abc5b9a3ce86fb0fbf881cf Mon Sep 17 00:00:00 2001 From: Sylwester Nawrocki Date: Sun, 6 Nov 2011 16:31:50 -0300 Subject: [media] staging: as102: Eliminate as10x_handle_t alias Remove pre-processor defined as10x_handle_t data type by directly replacing it with struct as102_bus_adapter_t. phandle is renamed to adap inside function bodies. Cc: Devin Heitmueller Signed-off-by: Sylwester Nawrocki Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/staging/media/as102/as102_drv.c b/drivers/staging/media/as102/as102_drv.c index 44f6017..b8adfd2 100644 --- a/drivers/staging/media/as102/as102_drv.c +++ b/drivers/staging/media/as102/as102_drv.c @@ -60,7 +60,7 @@ DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); static void as102_stop_stream(struct as102_dev_t *dev) { - struct as102_bus_adapter_t *bus_adap; + struct as10x_bus_adapter_t *bus_adap; if (dev != NULL) bus_adap = &dev->bus_adap; @@ -83,7 +83,7 @@ static void as102_stop_stream(struct as102_dev_t *dev) static int as102_start_stream(struct as102_dev_t *dev) { - struct as102_bus_adapter_t *bus_adap; + struct as10x_bus_adapter_t *bus_adap; int ret = -EFAULT; if (dev != NULL) @@ -109,7 +109,7 @@ static int as102_start_stream(struct as102_dev_t *dev) static int as10x_pid_filter(struct as102_dev_t *dev, int index, u16 pid, int onoff) { - struct as102_bus_adapter_t *bus_adap = &dev->bus_adap; + struct as10x_bus_adapter_t *bus_adap = &dev->bus_adap; int ret = -EFAULT; ENTER(); diff --git a/drivers/staging/media/as102/as102_drv.h b/drivers/staging/media/as102/as102_drv.h index 06466fd..0ecef9e 100644 --- a/drivers/staging/media/as102/as102_drv.h +++ b/drivers/staging/media/as102/as102_drv.h @@ -50,7 +50,7 @@ extern int elna_enable; #define AS102_USB_BUF_SIZE 512 #define MAX_STREAM_URB 32 -struct as102_bus_adapter_t { +struct as10x_bus_adapter_t { struct usb_device *usb_dev; /* bus token lock */ struct mutex lock; @@ -72,7 +72,7 @@ struct as102_bus_adapter_t { struct as102_dev_t { const char *name; - struct as102_bus_adapter_t bus_adap; + struct as10x_bus_adapter_t bus_adap; struct list_head device_entry; struct kref kref; unsigned long minor; diff --git a/drivers/staging/media/as102/as102_fw.c b/drivers/staging/media/as102/as102_fw.c index fa56939..43ebc43 100644 --- a/drivers/staging/media/as102/as102_fw.c +++ b/drivers/staging/media/as102/as102_fw.c @@ -101,7 +101,7 @@ static int parse_hex_line(unsigned char *fw_data, unsigned char *addr, return (count * 2) + 2; } -static int as102_firmware_upload(struct as102_bus_adapter_t *bus_adap, +static int as102_firmware_upload(struct as10x_bus_adapter_t *bus_adap, unsigned char *cmd, const struct firmware *firmware) { @@ -162,7 +162,7 @@ error: return (errno == 0) ? total_read_bytes : errno; } -int as102_fw_upload(struct as102_bus_adapter_t *bus_adap) +int as102_fw_upload(struct as10x_bus_adapter_t *bus_adap) { int errno = -EFAULT; const struct firmware *firmware; diff --git a/drivers/staging/media/as102/as102_fw.h b/drivers/staging/media/as102/as102_fw.h index a1fdb92..bd21f05 100644 --- a/drivers/staging/media/as102/as102_fw.h +++ b/drivers/staging/media/as102/as102_fw.h @@ -34,5 +34,5 @@ struct as10x_fw_pkt_t { } __packed; #ifdef __KERNEL__ -int as102_fw_upload(struct as102_bus_adapter_t *bus_adap); +int as102_fw_upload(struct as10x_bus_adapter_t *bus_adap); #endif diff --git a/drivers/staging/media/as102/as102_usb_drv.c b/drivers/staging/media/as102/as102_usb_drv.c index 97bceeb..9faab5b 100644 --- a/drivers/staging/media/as102/as102_usb_drv.c +++ b/drivers/staging/media/as102/as102_usb_drv.c @@ -74,7 +74,7 @@ static struct usb_class_driver as102_usb_class_driver = { .minor_base = AS102_DEVICE_MAJOR, }; -static int as102_usb_xfer_cmd(struct as102_bus_adapter_t *bus_adap, +static int as102_usb_xfer_cmd(struct as10x_bus_adapter_t *bus_adap, unsigned char *send_buf, int send_buf_len, unsigned char *recv_buf, int recv_buf_len) { @@ -131,7 +131,7 @@ static int as102_usb_xfer_cmd(struct as102_bus_adapter_t *bus_adap, return ret; } -static int as102_send_ep1(struct as102_bus_adapter_t *bus_adap, +static int as102_send_ep1(struct as10x_bus_adapter_t *bus_adap, unsigned char *send_buf, int send_buf_len, int swap32) @@ -154,7 +154,7 @@ static int as102_send_ep1(struct as102_bus_adapter_t *bus_adap, return ret ? ret : actual_len; } -static int as102_read_ep2(struct as102_bus_adapter_t *bus_adap, +static int as102_read_ep2(struct as10x_bus_adapter_t *bus_adap, unsigned char *recv_buf, int recv_buf_len) { int ret = 0, actual_len; diff --git a/drivers/staging/media/as102/as10x_cmd.c b/drivers/staging/media/as102/as10x_cmd.c index 1663a45..0387bb8 100644 --- a/drivers/staging/media/as102/as10x_cmd.c +++ b/drivers/staging/media/as102/as10x_cmd.c @@ -25,35 +25,35 @@ /** * as10x_cmd_turn_on - send turn on command to AS10x - * @phandle: pointer to AS10x handle + * @adap: pointer to AS10x bus adapter * * Return 0 when no error, < 0 in case of error. */ -int as10x_cmd_turn_on(as10x_handle_t *phandle) +int as10x_cmd_turn_on(struct as10x_bus_adapter_t *adap) { int error; struct as10x_cmd_t *pcmd, *prsp; ENTER(); - pcmd = phandle->cmd; - prsp = phandle->rsp; + pcmd = adap->cmd; + prsp = adap->rsp; /* prepare command */ - as10x_cmd_build(pcmd, (++phandle->cmd_xid), + as10x_cmd_build(pcmd, (++adap->cmd_xid), sizeof(pcmd->body.turn_on.req)); /* fill command */ pcmd->body.turn_on.req.proc_id = cpu_to_le16(CONTROL_PROC_TURNON); /* send command */ - if (phandle->ops->xfer_cmd) { - error = phandle->ops->xfer_cmd(phandle, (uint8_t *) pcmd, - sizeof(pcmd->body.turn_on.req) + - HEADER_SIZE, - (uint8_t *) prsp, - sizeof(prsp->body.turn_on.rsp) + - HEADER_SIZE); + if (adap->ops->xfer_cmd) { + error = adap->ops->xfer_cmd(adap, (uint8_t *) pcmd, + sizeof(pcmd->body.turn_on.req) + + HEADER_SIZE, + (uint8_t *) prsp, + sizeof(prsp->body.turn_on.rsp) + + HEADER_SIZE); } else { error = AS10X_CMD_ERROR; } @@ -71,31 +71,31 @@ out: /** * as10x_cmd_turn_off - send turn off command to AS10x - * @phandle: pointer to AS10x handle + * @adap: pointer to AS10x bus adapter * * Return 0 on success or negative value in case of error. */ -int as10x_cmd_turn_off(as10x_handle_t *phandle) +int as10x_cmd_turn_off(struct as10x_bus_adapter_t *adap) { int error; struct as10x_cmd_t *pcmd, *prsp; ENTER(); - pcmd = phandle->cmd; - prsp = phandle->rsp; + pcmd = adap->cmd; + prsp = adap->rsp; /* prepare command */ - as10x_cmd_build(pcmd, (++phandle->cmd_xid), + as10x_cmd_build(pcmd, (++adap->cmd_xid), sizeof(pcmd->body.turn_off.req)); /* fill command */ pcmd->body.turn_off.req.proc_id = cpu_to_le16(CONTROL_PROC_TURNOFF); /* send command */ - if (phandle->ops->xfer_cmd) { - error = phandle->ops->xfer_cmd( - phandle, (uint8_t *) pcmd, + if (adap->ops->xfer_cmd) { + error = adap->ops->xfer_cmd( + adap, (uint8_t *) pcmd, sizeof(pcmd->body.turn_off.req) + HEADER_SIZE, (uint8_t *) prsp, sizeof(prsp->body.turn_off.rsp) + HEADER_SIZE); @@ -116,23 +116,24 @@ out: /** * as10x_cmd_set_tune - send set tune command to AS10x - * @phandle: pointer to AS10x handle + * @adap: pointer to AS10x bus adapter * @ptune: tune parameters * * Return 0 on success or negative value in case of error. */ -int as10x_cmd_set_tune(as10x_handle_t *phandle, struct as10x_tune_args *ptune) +int as10x_cmd_set_tune(struct as10x_bus_adapter_t *adap, + struct as10x_tune_args *ptune) { int error; struct as10x_cmd_t *preq, *prsp; ENTER(); - preq = phandle->cmd; - prsp = phandle->rsp; + preq = adap->cmd; + prsp = adap->rsp; /* prepare command */ - as10x_cmd_build(preq, (++phandle->cmd_xid), + as10x_cmd_build(preq, (++adap->cmd_xid), sizeof(preq->body.set_tune.req)); /* fill command */ @@ -150,14 +151,14 @@ int as10x_cmd_set_tune(as10x_handle_t *phandle, struct as10x_tune_args *ptune) ptune->transmission_mode; /* send command */ - if (phandle->ops->xfer_cmd) { - error = phandle->ops->xfer_cmd(phandle, - (uint8_t *) preq, - sizeof(preq->body.set_tune.req) - + HEADER_SIZE, - (uint8_t *) prsp, - sizeof(prsp->body.set_tune.rsp) - + HEADER_SIZE); + if (adap->ops->xfer_cmd) { + error = adap->ops->xfer_cmd(adap, + (uint8_t *) preq, + sizeof(preq->body.set_tune.req) + + HEADER_SIZE, + (uint8_t *) prsp, + sizeof(prsp->body.set_tune.rsp) + + HEADER_SIZE); } else { error = AS10X_CMD_ERROR; } @@ -175,12 +176,12 @@ out: /** * as10x_cmd_get_tune_status - send get tune status command to AS10x - * @phandle: pointer to AS10x handle + * @adap: pointer to AS10x bus adapter * @pstatus: pointer to updated status structure of the current tune * * Return 0 on success or negative value in case of error. */ -int as10x_cmd_get_tune_status(as10x_handle_t *phandle, +int as10x_cmd_get_tune_status(struct as10x_bus_adapter_t *adap, struct as10x_tune_status *pstatus) { int error; @@ -188,11 +189,11 @@ int as10x_cmd_get_tune_status(as10x_handle_t *phandle, ENTER(); - preq = phandle->cmd; - prsp = phandle->rsp; + preq = adap->cmd; + prsp = adap->rsp; /* prepare command */ - as10x_cmd_build(preq, (++phandle->cmd_xid), + as10x_cmd_build(preq, (++adap->cmd_xid), sizeof(preq->body.get_tune_status.req)); /* fill command */ @@ -200,9 +201,9 @@ int as10x_cmd_get_tune_status(as10x_handle_t *phandle, cpu_to_le16(CONTROL_PROC_GETTUNESTAT); /* send command */ - if (phandle->ops->xfer_cmd) { - error = phandle->ops->xfer_cmd( - phandle, + if (adap->ops->xfer_cmd) { + error = adap->ops->xfer_cmd( + adap, (uint8_t *) preq, sizeof(preq->body.get_tune_status.req) + HEADER_SIZE, (uint8_t *) prsp, @@ -233,23 +234,23 @@ out: /** * as10x_cmd_get_tps - send get TPS command to AS10x - * @phandle: pointer to AS10x handle + * @adap: pointer to AS10x handle * @ptps: pointer to TPS parameters structure * * Return 0 on success or negative value in case of error. */ -int as10x_cmd_get_tps(as10x_handle_t *phandle, struct as10x_tps *ptps) +int as10x_cmd_get_tps(struct as10x_bus_adapter_t *adap, struct as10x_tps *ptps) { int error; struct as10x_cmd_t *pcmd, *prsp; ENTER(); - pcmd = phandle->cmd; - prsp = phandle->rsp; + pcmd = adap->cmd; + prsp = adap->rsp; /* prepare command */ - as10x_cmd_build(pcmd, (++phandle->cmd_xid), + as10x_cmd_build(pcmd, (++adap->cmd_xid), sizeof(pcmd->body.get_tps.req)); /* fill command */ @@ -257,14 +258,14 @@ int as10x_cmd_get_tps(as10x_handle_t *phandle, struct as10x_tps *ptps) cpu_to_le16(CONTROL_PROC_GETTPS); /* send command */ - if (phandle->ops->xfer_cmd) { - error = phandle->ops->xfer_cmd(phandle, - (uint8_t *) pcmd, - sizeof(pcmd->body.get_tps.req) + - HEADER_SIZE, - (uint8_t *) prsp, - sizeof(prsp->body.get_tps.rsp) + - HEADER_SIZE); + if (adap->ops->xfer_cmd) { + error = adap->ops->xfer_cmd(adap, + (uint8_t *) pcmd, + sizeof(pcmd->body.get_tps.req) + + HEADER_SIZE, + (uint8_t *) prsp, + sizeof(prsp->body.get_tps.rsp) + + HEADER_SIZE); } else { error = AS10X_CMD_ERROR; } @@ -296,12 +297,12 @@ out: /** * as10x_cmd_get_demod_stats - send get demod stats command to AS10x - * @phandle: pointer to AS10x handle + * @adap: pointer to AS10x bus adapter * @pdemod_stats: pointer to demod stats parameters structure * * Return 0 on success or negative value in case of error. */ -int as10x_cmd_get_demod_stats(as10x_handle_t *phandle, +int as10x_cmd_get_demod_stats(struct as10x_bus_adapter_t *adap, struct as10x_demod_stats *pdemod_stats) { int error; @@ -309,11 +310,11 @@ int as10x_cmd_get_demod_stats(as10x_handle_t *phandle, ENTER(); - pcmd = phandle->cmd; - prsp = phandle->rsp; + pcmd = adap->cmd; + prsp = adap->rsp; /* prepare command */ - as10x_cmd_build(pcmd, (++phandle->cmd_xid), + as10x_cmd_build(pcmd, (++adap->cmd_xid), sizeof(pcmd->body.get_demod_stats.req)); /* fill command */ @@ -321,8 +322,8 @@ int as10x_cmd_get_demod_stats(as10x_handle_t *phandle, cpu_to_le16(CONTROL_PROC_GET_DEMOD_STATS); /* send command */ - if (phandle->ops->xfer_cmd) { - error = phandle->ops->xfer_cmd(phandle, + if (adap->ops->xfer_cmd) { + error = adap->ops->xfer_cmd(adap, (uint8_t *) pcmd, sizeof(pcmd->body.get_demod_stats.req) + HEADER_SIZE, @@ -360,13 +361,13 @@ out: /** * as10x_cmd_get_impulse_resp - send get impulse response command to AS10x - * @phandle: pointer to AS10x handle + * @adap: pointer to AS10x bus adapter * @is_ready: pointer to value indicating when impulse * response data is ready * * Return 0 on success or negative value in case of error. */ -int as10x_cmd_get_impulse_resp(as10x_handle_t *phandle, +int as10x_cmd_get_impulse_resp(struct as10x_bus_adapter_t *adap, uint8_t *is_ready) { int error; @@ -374,11 +375,11 @@ int as10x_cmd_get_impulse_resp(as10x_handle_t *phandle, ENTER(); - pcmd = phandle->cmd; - prsp = phandle->rsp; + pcmd = adap->cmd; + prsp = adap->rsp; /* prepare command */ - as10x_cmd_build(pcmd, (++phandle->cmd_xid), + as10x_cmd_build(pcmd, (++adap->cmd_xid), sizeof(pcmd->body.get_impulse_rsp.req)); /* fill command */ @@ -386,8 +387,8 @@ int as10x_cmd_get_impulse_resp(as10x_handle_t *phandle, cpu_to_le16(CONTROL_PROC_GET_IMPULSE_RESP); /* send command */ - if (phandle->ops->xfer_cmd) { - error = phandle->ops->xfer_cmd(phandle, + if (adap->ops->xfer_cmd) { + error = adap->ops->xfer_cmd(adap, (uint8_t *) pcmd, sizeof(pcmd->body.get_impulse_rsp.req) + HEADER_SIZE, diff --git a/drivers/staging/media/as102/as10x_cmd.h b/drivers/staging/media/as102/as10x_cmd.h index da31c6d..4ea249e 100644 --- a/drivers/staging/media/as102/as10x_cmd.h +++ b/drivers/staging/media/as102/as10x_cmd.h @@ -489,41 +489,41 @@ void as10x_cmd_build(struct as10x_cmd_t *pcmd, uint16_t proc_id, int as10x_rsp_parse(struct as10x_cmd_t *r, uint16_t proc_id); /* as10x cmd */ -int as10x_cmd_turn_on(as10x_handle_t *phandle); -int as10x_cmd_turn_off(as10x_handle_t *phandle); +int as10x_cmd_turn_on(struct as10x_bus_adapter_t *adap); +int as10x_cmd_turn_off(struct as10x_bus_adapter_t *adap); -int as10x_cmd_set_tune(as10x_handle_t *phandle, +int as10x_cmd_set_tune(struct as10x_bus_adapter_t *adap, struct as10x_tune_args *ptune); -int as10x_cmd_get_tune_status(as10x_handle_t *phandle, +int as10x_cmd_get_tune_status(struct as10x_bus_adapter_t *adap, struct as10x_tune_status *pstatus); -int as10x_cmd_get_tps(as10x_handle_t *phandle, +int as10x_cmd_get_tps(struct as10x_bus_adapter_t *adap, struct as10x_tps *ptps); -int as10x_cmd_get_demod_stats(as10x_handle_t *phandle, +int as10x_cmd_get_demod_stats(struct as10x_bus_adapter_t *adap, struct as10x_demod_stats *pdemod_stats); -int as10x_cmd_get_impulse_resp(as10x_handle_t *phandle, +int as10x_cmd_get_impulse_resp(struct as10x_bus_adapter_t *adap, uint8_t *is_ready); /* as10x cmd stream */ -int as10x_cmd_add_PID_filter(as10x_handle_t *phandle, +int as10x_cmd_add_PID_filter(struct as10x_bus_adapter_t *adap, struct as10x_ts_filter *filter); -int as10x_cmd_del_PID_filter(as10x_handle_t *phandle, +int as10x_cmd_del_PID_filter(struct as10x_bus_adapter_t *adap, uint16_t pid_value); -int as10x_cmd_start_streaming(as10x_handle_t *phandle); -int as10x_cmd_stop_streaming(as10x_handle_t *phandle); +int as10x_cmd_start_streaming(struct as10x_bus_adapter_t *adap); +int as10x_cmd_stop_streaming(struct as10x_bus_adapter_t *adap); /* as10x cmd cfg */ -int as10x_cmd_set_context(as10x_handle_t *phandle, +int as10x_cmd_set_context(struct as10x_bus_adapter_t *adap, uint16_t tag, uint32_t value); -int as10x_cmd_get_context(as10x_handle_t *phandle, +int as10x_cmd_get_context(struct as10x_bus_adapter_t *adap, uint16_t tag, uint32_t *pvalue); -int as10x_cmd_eLNA_change_mode(as10x_handle_t *phandle, uint8_t mode); +int as10x_cmd_eLNA_change_mode(struct as10x_bus_adapter_t *adap, uint8_t mode); int as10x_context_rsp_parse(struct as10x_cmd_t *prsp, uint16_t proc_id); #endif diff --git a/drivers/staging/media/as102/as10x_cmd_cfg.c b/drivers/staging/media/as102/as10x_cmd_cfg.c index ec6f69f..d2a4bce 100644 --- a/drivers/staging/media/as102/as10x_cmd_cfg.c +++ b/drivers/staging/media/as102/as10x_cmd_cfg.c @@ -28,13 +28,13 @@ /** * as10x_cmd_get_context - Send get context command to AS10x - * @phandle: pointer to AS10x handle + * @adap: pointer to AS10x bus adapter * @tag: context tag * @pvalue: pointer where to store context value read * * Return 0 on success or negative value in case of error. */ -int as10x_cmd_get_context(as10x_handle_t *phandle, uint16_t tag, +int as10x_cmd_get_context(struct as10x_bus_adapter_t *adap, uint16_t tag, uint32_t *pvalue) { int error; @@ -42,11 +42,11 @@ int as10x_cmd_get_context(as10x_handle_t *phandle, uint16_t tag, ENTER(); - pcmd = phandle->cmd; - prsp = phandle->rsp; + pcmd = adap->cmd; + prsp = adap->rsp; /* prepare command */ - as10x_cmd_build(pcmd, (++phandle->cmd_xid), + as10x_cmd_build(pcmd, (++adap->cmd_xid), sizeof(pcmd->body.context.req)); /* fill command */ @@ -55,14 +55,14 @@ int as10x_cmd_get_context(as10x_handle_t *phandle, uint16_t tag, pcmd->body.context.req.type = cpu_to_le16(GET_CONTEXT_DATA); /* send command */ - if (phandle->ops->xfer_cmd) { - error = phandle->ops->xfer_cmd(phandle, - (uint8_t *) pcmd, - sizeof(pcmd->body.context.req) - + HEADER_SIZE, - (uint8_t *) prsp, - sizeof(prsp->body.context.rsp) - + HEADER_SIZE); + if (adap->ops->xfer_cmd) { + error = adap->ops->xfer_cmd(adap, + (uint8_t *) pcmd, + sizeof(pcmd->body.context.req) + + HEADER_SIZE, + (uint8_t *) prsp, + sizeof(prsp->body.context.rsp) + + HEADER_SIZE); } else { error = AS10X_CMD_ERROR; } @@ -87,13 +87,13 @@ out: /** * as10x_cmd_set_context - send set context command to AS10x - * @phandle: pointer to AS10x handle + * @adap: pointer to AS10x bus adapter * @tag: context tag * @value: value to set in context * * Return 0 on success or negative value in case of error. */ -int as10x_cmd_set_context(as10x_handle_t *phandle, uint16_t tag, +int as10x_cmd_set_context(struct as10x_bus_adapter_t *adap, uint16_t tag, uint32_t value) { int error; @@ -101,11 +101,11 @@ int as10x_cmd_set_context(as10x_handle_t *phandle, uint16_t tag, ENTER(); - pcmd = phandle->cmd; - prsp = phandle->rsp; + pcmd = adap->cmd; + prsp = adap->rsp; /* prepare command */ - as10x_cmd_build(pcmd, (++phandle->cmd_xid), + as10x_cmd_build(pcmd, (++adap->cmd_xid), sizeof(pcmd->body.context.req)); /* fill command */ @@ -116,14 +116,14 @@ int as10x_cmd_set_context(as10x_handle_t *phandle, uint16_t tag, pcmd->body.context.req.type = cpu_to_le16(SET_CONTEXT_DATA); /* send command */ - if (phandle->ops->xfer_cmd) { - error = phandle->ops->xfer_cmd(phandle, - (uint8_t *) pcmd, - sizeof(pcmd->body.context.req) - + HEADER_SIZE, - (uint8_t *) prsp, - sizeof(prsp->body.context.rsp) - + HEADER_SIZE); + if (adap->ops->xfer_cmd) { + error = adap->ops->xfer_cmd(adap, + (uint8_t *) pcmd, + sizeof(pcmd->body.context.req) + + HEADER_SIZE, + (uint8_t *) prsp, + sizeof(prsp->body.context.rsp) + + HEADER_SIZE); } else { error = AS10X_CMD_ERROR; } @@ -142,7 +142,7 @@ out: /** * as10x_cmd_eLNA_change_mode - send eLNA change mode command to AS10x - * @phandle: pointer to AS10x handle + * @adap: pointer to AS10x bus adapter * @mode: mode selected: * - ON : 0x0 => eLNA always ON * - OFF : 0x1 => eLNA always OFF @@ -151,18 +151,18 @@ out: * * Return 0 on success or negative value in case of error. */ -int as10x_cmd_eLNA_change_mode(as10x_handle_t *phandle, uint8_t mode) +int as10x_cmd_eLNA_change_mode(struct as10x_bus_adapter_t *adap, uint8_t mode) { int error; struct as10x_cmd_t *pcmd, *prsp; ENTER(); - pcmd = phandle->cmd; - prsp = phandle->rsp; + pcmd = adap->cmd; + prsp = adap->rsp; /* prepare command */ - as10x_cmd_build(pcmd, (++phandle->cmd_xid), + as10x_cmd_build(pcmd, (++adap->cmd_xid), sizeof(pcmd->body.cfg_change_mode.req)); /* fill command */ @@ -171,8 +171,8 @@ int as10x_cmd_eLNA_change_mode(as10x_handle_t *phandle, uint8_t mode) pcmd->body.cfg_change_mode.req.mode = mode; /* send command */ - if (phandle->ops->xfer_cmd) { - error = phandle->ops->xfer_cmd(phandle, (uint8_t *) pcmd, + if (adap->ops->xfer_cmd) { + error = adap->ops->xfer_cmd(adap, (uint8_t *) pcmd, sizeof(pcmd->body.cfg_change_mode.req) + HEADER_SIZE, (uint8_t *) prsp, sizeof(prsp->body.cfg_change_mode.rsp) diff --git a/drivers/staging/media/as102/as10x_cmd_stream.c b/drivers/staging/media/as102/as10x_cmd_stream.c index 045c706..6d000f6 100644 --- a/drivers/staging/media/as102/as10x_cmd_stream.c +++ b/drivers/staging/media/as102/as10x_cmd_stream.c @@ -23,12 +23,12 @@ /** * as10x_cmd_add_PID_filter - send add filter command to AS10x - * @phandle: pointer to AS10x handle + * @adap: pointer to AS10x bus adapter * @filter: TSFilter filter for DVB-T * * Return 0 on success or negative value in case of error. */ -int as10x_cmd_add_PID_filter(as10x_handle_t *phandle, +int as10x_cmd_add_PID_filter(struct as10x_bus_adapter_t *adap, struct as10x_ts_filter *filter) { int error; @@ -36,11 +36,11 @@ int as10x_cmd_add_PID_filter(as10x_handle_t *phandle, ENTER(); - pcmd = phandle->cmd; - prsp = phandle->rsp; + pcmd = adap->cmd; + prsp = adap->rsp; /* prepare command */ - as10x_cmd_build(pcmd, (++phandle->cmd_xid), + as10x_cmd_build(pcmd, (++adap->cmd_xid), sizeof(pcmd->body.add_pid_filter.req)); /* fill command */ @@ -55,8 +55,8 @@ int as10x_cmd_add_PID_filter(as10x_handle_t *phandle, pcmd->body.add_pid_filter.req.idx = 0xFF; /* send command */ - if (phandle->ops->xfer_cmd) { - error = phandle->ops->xfer_cmd(phandle, (uint8_t *) pcmd, + if (adap->ops->xfer_cmd) { + error = adap->ops->xfer_cmd(adap, (uint8_t *) pcmd, sizeof(pcmd->body.add_pid_filter.req) + HEADER_SIZE, (uint8_t *) prsp, sizeof(prsp->body.add_pid_filter.rsp) @@ -83,12 +83,12 @@ out: /** * as10x_cmd_del_PID_filter - Send delete filter command to AS10x - * @phandle: pointer to AS10x handle + * @adap: pointer to AS10x bus adapte * @pid_value: PID to delete * * Return 0 on success or negative value in case of error. */ -int as10x_cmd_del_PID_filter(as10x_handle_t *phandle, +int as10x_cmd_del_PID_filter(struct as10x_bus_adapter_t *adap, uint16_t pid_value) { int error; @@ -96,11 +96,11 @@ int as10x_cmd_del_PID_filter(as10x_handle_t *phandle, ENTER(); - pcmd = phandle->cmd; - prsp = phandle->rsp; + pcmd = adap->cmd; + prsp = adap->rsp; /* prepare command */ - as10x_cmd_build(pcmd, (++phandle->cmd_xid), + as10x_cmd_build(pcmd, (++adap->cmd_xid), sizeof(pcmd->body.del_pid_filter.req)); /* fill command */ @@ -109,8 +109,8 @@ int as10x_cmd_del_PID_filter(as10x_handle_t *phandle, pcmd->body.del_pid_filter.req.pid = cpu_to_le16(pid_value); /* send command */ - if (phandle->ops->xfer_cmd) { - error = phandle->ops->xfer_cmd(phandle, (uint8_t *) pcmd, + if (adap->ops->xfer_cmd) { + error = adap->ops->xfer_cmd(adap, (uint8_t *) pcmd, sizeof(pcmd->body.del_pid_filter.req) + HEADER_SIZE, (uint8_t *) prsp, sizeof(prsp->body.del_pid_filter.rsp) @@ -132,22 +132,22 @@ out: /** * as10x_cmd_start_streaming - Send start streaming command to AS10x - * @phandle: pointer to AS10x handle + * @adap: pointer to AS10x bus adapter * * Return 0 on success or negative value in case of error. */ -int as10x_cmd_start_streaming(as10x_handle_t *phandle) +int as10x_cmd_start_streaming(struct as10x_bus_adapter_t *adap) { int error; struct as10x_cmd_t *pcmd, *prsp; ENTER(); - pcmd = phandle->cmd; - prsp = phandle->rsp; + pcmd = adap->cmd; + prsp = adap->rsp; /* prepare command */ - as10x_cmd_build(pcmd, (++phandle->cmd_xid), + as10x_cmd_build(pcmd, (++adap->cmd_xid), sizeof(pcmd->body.start_streaming.req)); /* fill command */ @@ -155,8 +155,8 @@ int as10x_cmd_start_streaming(as10x_handle_t *phandle) cpu_to_le16(CONTROL_PROC_START_STREAMING); /* send command */ - if (phandle->ops->xfer_cmd) { - error = phandle->ops->xfer_cmd(phandle, (uint8_t *) pcmd, + if (adap->ops->xfer_cmd) { + error = adap->ops->xfer_cmd(adap, (uint8_t *) pcmd, sizeof(pcmd->body.start_streaming.req) + HEADER_SIZE, (uint8_t *) prsp, sizeof(prsp->body.start_streaming.rsp) @@ -178,22 +178,22 @@ out: /** * as10x_cmd_stop_streaming - Send stop streaming command to AS10x - * @phandle: pointer to AS10x handle + * @adap: pointer to AS10x bus adapter * * Return 0 on success or negative value in case of error. */ -int as10x_cmd_stop_streaming(as10x_handle_t *phandle) +int as10x_cmd_stop_streaming(struct as10x_bus_adapter_t *adap) { int8_t error; struct as10x_cmd_t *pcmd, *prsp; ENTER(); - pcmd = phandle->cmd; - prsp = phandle->rsp; + pcmd = adap->cmd; + prsp = adap->rsp; /* prepare command */ - as10x_cmd_build(pcmd, (++phandle->cmd_xid), + as10x_cmd_build(pcmd, (++adap->cmd_xid), sizeof(pcmd->body.stop_streaming.req)); /* fill command */ @@ -201,8 +201,8 @@ int as10x_cmd_stop_streaming(as10x_handle_t *phandle) cpu_to_le16(CONTROL_PROC_STOP_STREAMING); /* send command */ - if (phandle->ops->xfer_cmd) { - error = phandle->ops->xfer_cmd(phandle, (uint8_t *) pcmd, + if (adap->ops->xfer_cmd) { + error = adap->ops->xfer_cmd(adap, (uint8_t *) pcmd, sizeof(pcmd->body.stop_streaming.req) + HEADER_SIZE, (uint8_t *) prsp, sizeof(prsp->body.stop_streaming.rsp) diff --git a/drivers/staging/media/as102/as10x_handle.h b/drivers/staging/media/as102/as10x_handle.h index d67203a..62b9795 100644 --- a/drivers/staging/media/as102/as10x_handle.h +++ b/drivers/staging/media/as102/as10x_handle.h @@ -17,10 +17,9 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifdef __KERNEL__ -struct as102_bus_adapter_t; +struct as10x_bus_adapter_t; struct as102_dev_t; -#define as10x_handle_t struct as102_bus_adapter_t #include "as10x_cmd.h" /* values for "mode" field */ @@ -29,29 +28,26 @@ struct as102_dev_t; #define REGMODE32 32 struct as102_priv_ops_t { - int (*upload_fw_pkt) (struct as102_bus_adapter_t *bus_adap, + int (*upload_fw_pkt) (struct as10x_bus_adapter_t *bus_adap, unsigned char *buf, int buflen, int swap32); - int (*send_cmd) (struct as102_bus_adapter_t *bus_adap, + int (*send_cmd) (struct as10x_bus_adapter_t *bus_adap, unsigned char *buf, int buflen); - int (*xfer_cmd) (struct as102_bus_adapter_t *bus_adap, + int (*xfer_cmd) (struct as10x_bus_adapter_t *bus_adap, unsigned char *send_buf, int send_buf_len, unsigned char *recv_buf, int recv_buf_len); -/* - int (*pid_filter) (struct as102_bus_adapter_t *bus_adap, - int index, u16 pid, int onoff); -*/ + int (*start_stream) (struct as102_dev_t *dev); void (*stop_stream) (struct as102_dev_t *dev); - int (*reset_target) (struct as102_bus_adapter_t *bus_adap); + int (*reset_target) (struct as10x_bus_adapter_t *bus_adap); - int (*read_write)(struct as102_bus_adapter_t *bus_adap, uint8_t mode, + int (*read_write)(struct as10x_bus_adapter_t *bus_adap, uint8_t mode, uint32_t rd_addr, uint16_t rd_len, uint32_t wr_addr, uint16_t wr_len); - int (*as102_read_ep2) (struct as102_bus_adapter_t *bus_adap, + int (*as102_read_ep2) (struct as10x_bus_adapter_t *bus_adap, unsigned char *recv_buf, int recv_buf_len); }; -- cgit v0.10.2 From fdb5a9111ef77d537efb86e90e8073ebfd0b553e Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Sun, 6 Nov 2011 18:30:26 -0300 Subject: [media] Support for Sveon STV22 (IT9137) This indeed a clone of Kworld UB499 2T Signed-off-by: Malcolm Priestley Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h index 2d08c9b..0040aa2 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h +++ b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h @@ -322,6 +322,7 @@ #define USB_PID_TVWAY_PLUS 0x0002 #define USB_PID_SVEON_STV20 0xe39d #define USB_PID_SVEON_STV22 0xe401 +#define USB_PID_SVEON_STV22_IT9137 0xe411 #define USB_PID_AZUREWAVE_AZ6027 0x3275 #define USB_PID_TERRATEC_DVBS2CI_V1 0x10a4 #define USB_PID_TERRATEC_DVBS2CI_V2 0x10ac diff --git a/drivers/media/dvb/dvb-usb/it913x.c b/drivers/media/dvb/dvb-usb/it913x.c index 9f58241..9abdaee 100644 --- a/drivers/media/dvb/dvb-usb/it913x.c +++ b/drivers/media/dvb/dvb-usb/it913x.c @@ -577,6 +577,7 @@ static int it913x_probe(struct usb_interface *intf, static struct usb_device_id it913x_table[] = { { USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_UB499_2T_T09) }, { USB_DEVICE(USB_VID_ITETECH, USB_PID_ITETECH_IT9135) }, + { USB_DEVICE(USB_VID_KWORLD_2, USB_PID_SVEON_STV22_IT9137) }, {} /* Terminating entry */ }; @@ -652,7 +653,7 @@ static struct dvb_usb_device_properties it913x_properties = { .rc_codes = RC_MAP_KWORLD_315U, }, .i2c_algo = &it913x_i2c_algo, - .num_device_descs = 2, + .num_device_descs = 3, .devices = { { "Kworld UB499-2T T09(IT9137)", { &it913x_table[0], NULL }, @@ -660,6 +661,9 @@ static struct dvb_usb_device_properties it913x_properties = { { "ITE 9135 Generic", { &it913x_table[1], NULL }, }, + { "Sveon STV22 Dual DVB-T HDTV(IT9137)", + { &it913x_table[2], NULL }, + }, } }; -- cgit v0.10.2 From 819cd82b0a994d9d83dc1d1ced1088e71d702d4c Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Mon, 7 Nov 2011 05:24:49 -0300 Subject: [media] usbvision: Drop broken 10-bit I2C address support The support for 10-bit I2C addresses in usbvision seems plain broken to me. I had already noticed that back in February 2007 [1]. The code was not fixed since then, so I take it that it's not actually needed. And as a matter of fact I don't know of any 10-bit addressed I2C tuner, encode, decoder or the like. So let's simply get rid of the broken and useless code. I'm also adding I2C_FUNC_I2C, as the driver and hardware support plain I2C messaging. [1] http://marc.info/?l=linux-i2c&m=117499415208244&w=2 Signed-off-by: Jean Delvare Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/usbvision/usbvision-i2c.c b/drivers/media/video/usbvision/usbvision-i2c.c index d7f9751..89fec02 100644 --- a/drivers/media/video/usbvision/usbvision-i2c.c +++ b/drivers/media/video/usbvision/usbvision-i2c.c @@ -110,42 +110,20 @@ static inline int usb_find_address(struct i2c_adapter *i2c_adap, unsigned char addr; int ret; - if ((flags & I2C_M_TEN)) { - /* a ten bit address */ - addr = 0xf0 | ((msg->addr >> 7) & 0x03); - /* try extended address code... */ - ret = try_write_address(i2c_adap, addr, retries); - if (ret != 1) { - dev_err(&i2c_adap->dev, - "died at extended address code, while writing\n"); - return -EREMOTEIO; - } - add[0] = addr; - if (flags & I2C_M_RD) { - /* okay, now switch into reading mode */ - addr |= 0x01; - ret = try_read_address(i2c_adap, addr, retries); - if (ret != 1) { - dev_err(&i2c_adap->dev, - "died at extended address code, while reading\n"); - return -EREMOTEIO; - } - } - } else { /* normal 7bit address */ - addr = (msg->addr << 1); - if (flags & I2C_M_RD) - addr |= 1; + addr = (msg->addr << 1); + if (flags & I2C_M_RD) + addr |= 1; - add[0] = addr; - if (flags & I2C_M_RD) - ret = try_read_address(i2c_adap, addr, retries); - else - ret = try_write_address(i2c_adap, addr, retries); + add[0] = addr; + if (flags & I2C_M_RD) + ret = try_read_address(i2c_adap, addr, retries); + else + ret = try_write_address(i2c_adap, addr, retries); + + if (ret != 1) + return -EREMOTEIO; - if (ret != 1) - return -EREMOTEIO; - } return 0; } @@ -184,7 +162,7 @@ usbvision_i2c_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msgs[], int num) static u32 functionality(struct i2c_adapter *adap) { - return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_10BIT_ADDR; + return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; } /* -----exported algorithm data: ------------------------------------- */ -- cgit v0.10.2 From 044ab15353dffd977770df3cb3c286240642a3f7 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 30 Sep 2011 05:05:35 -0300 Subject: [media] V4L menu: move USB drivers section to the top USB webcams are some of the most used V4L devices, so move it to a more prominent place in the menu instead of being at the end. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig index d960656..cf16dbc 100644 --- a/drivers/media/video/Kconfig +++ b/drivers/media/video/Kconfig @@ -580,6 +580,79 @@ config VIDEO_M52790 endmenu # encoder / decoder chips +# +# USB Multimedia device configuration +# + +menuconfig V4L_USB_DRIVERS + bool "V4L USB devices" + depends on USB + default y + +if V4L_USB_DRIVERS && USB + +source "drivers/media/video/uvc/Kconfig" + +source "drivers/media/video/gspca/Kconfig" + +source "drivers/media/video/pvrusb2/Kconfig" + +source "drivers/media/video/hdpvr/Kconfig" + +source "drivers/media/video/em28xx/Kconfig" + +source "drivers/media/video/tlg2300/Kconfig" + +source "drivers/media/video/cx231xx/Kconfig" + +source "drivers/media/video/tm6000/Kconfig" + +source "drivers/media/video/usbvision/Kconfig" + +source "drivers/media/video/et61x251/Kconfig" + +source "drivers/media/video/sn9c102/Kconfig" + +source "drivers/media/video/pwc/Kconfig" + +config USB_ZR364XX + tristate "USB ZR364XX Camera support" + depends on VIDEO_V4L2 + select VIDEOBUF_GEN + select VIDEOBUF_VMALLOC + ---help--- + Say Y here if you want to connect this type of camera to your + computer's USB port. + See for more info + and list of supported cameras. + + To compile this driver as a module, choose M here: the + module will be called zr364xx. + +config USB_STKWEBCAM + tristate "USB Syntek DC1125 Camera support" + depends on VIDEO_V4L2 && EXPERIMENTAL + ---help--- + Say Y here if you want to use this type of camera. + Supported devices are typically found in some Asus laptops, + with USB id 174f:a311 and 05e1:0501. Other Syntek cameras + may be supported by the stk11xx driver, from which this is + derived, see + + To compile this driver as a module, choose M here: the + module will be called stkwebcam. + +config USB_S2255 + tristate "USB Sensoray 2255 video capture device" + depends on VIDEO_V4L2 + select VIDEOBUF_VMALLOC + default n + help + Say Y here if you want support for the Sensoray 2255 USB device. + This driver can be compiled as a module, called s2255drv. + +endif # V4L_USB_DRIVERS + config VIDEO_SH_VOU tristate "SuperH VOU video output driver" depends on VIDEO_DEV && ARCH_SHMOBILE @@ -1002,78 +1075,6 @@ config VIDEO_S5P_MIPI_CSIS source "drivers/media/video/s5p-tv/Kconfig" -# -# USB Multimedia device configuration -# - -menuconfig V4L_USB_DRIVERS - bool "V4L USB devices" - depends on USB - default y - -if V4L_USB_DRIVERS && USB - -source "drivers/media/video/uvc/Kconfig" - -source "drivers/media/video/gspca/Kconfig" - -source "drivers/media/video/pvrusb2/Kconfig" - -source "drivers/media/video/hdpvr/Kconfig" - -source "drivers/media/video/em28xx/Kconfig" - -source "drivers/media/video/tlg2300/Kconfig" - -source "drivers/media/video/cx231xx/Kconfig" - -source "drivers/media/video/tm6000/Kconfig" - -source "drivers/media/video/usbvision/Kconfig" - -source "drivers/media/video/et61x251/Kconfig" - -source "drivers/media/video/sn9c102/Kconfig" - -source "drivers/media/video/pwc/Kconfig" - -config USB_ZR364XX - tristate "USB ZR364XX Camera support" - depends on VIDEO_V4L2 - select VIDEOBUF_GEN - select VIDEOBUF_VMALLOC - ---help--- - Say Y here if you want to connect this type of camera to your - computer's USB port. - See for more info - and list of supported cameras. - - To compile this driver as a module, choose M here: the - module will be called zr364xx. - -config USB_STKWEBCAM - tristate "USB Syntek DC1125 Camera support" - depends on VIDEO_V4L2 && EXPERIMENTAL - ---help--- - Say Y here if you want to use this type of camera. - Supported devices are typically found in some Asus laptops, - with USB id 174f:a311 and 05e1:0501. Other Syntek cameras - may be supported by the stk11xx driver, from which this is - derived, see - - To compile this driver as a module, choose M here: the - module will be called stkwebcam. - -config USB_S2255 - tristate "USB Sensoray 2255 video capture device" - depends on VIDEO_V4L2 - select VIDEOBUF_VMALLOC - default n - help - Say Y here if you want support for the Sensoray 2255 USB device. - This driver can be compiled as a module, called s2255drv. - -endif # V4L_USB_DRIVERS endif # VIDEO_CAPTURE_DRIVERS menuconfig V4L_MEM2MEM_DRIVERS -- cgit v0.10.2 From a3c581be78cbd8ab9106935cb760facc29e9ea2b Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 30 Sep 2011 09:03:06 -0300 Subject: [media] V4L menu: move ISA and parport drivers into their own submenu Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig index cf16dbc..256ff4a 100644 --- a/drivers/media/video/Kconfig +++ b/drivers/media/video/Kconfig @@ -692,49 +692,6 @@ source "drivers/media/video/omap/Kconfig" source "drivers/media/video/bt8xx/Kconfig" -config VIDEO_PMS - tristate "Mediavision Pro Movie Studio Video For Linux" - depends on ISA && VIDEO_V4L2 - help - Say Y if you have such a thing. - - To compile this driver as a module, choose M here: the - module will be called pms. - -config VIDEO_BWQCAM - tristate "Quickcam BW Video For Linux" - depends on PARPORT && VIDEO_V4L2 - help - Say Y have if you the black and white version of the QuickCam - camera. See the next option for the color version. - - To compile this driver as a module, choose M here: the - module will be called bw-qcam. - -config VIDEO_CQCAM - tristate "QuickCam Colour Video For Linux (EXPERIMENTAL)" - depends on EXPERIMENTAL && PARPORT && VIDEO_V4L2 - help - This is the video4linux driver for the colour version of the - Connectix QuickCam. If you have one of these cameras, say Y here, - otherwise say N. This driver does not work with the original - monochrome QuickCam, QuickCam VC or QuickClip. It is also available - as a module (c-qcam). - Read for more information. - -config VIDEO_W9966 - tristate "W9966CF Webcam (FlyCam Supra and others) Video For Linux" - depends on PARPORT_1284 && PARPORT && VIDEO_V4L2 - help - Video4linux driver for Winbond's w9966 based Webcams. - Currently tested with the LifeView FlyCam Supra. - If you have one of these cameras, say Y here - otherwise say N. - This driver is also available as a module (w9966). - - Check out for more - information. - source "drivers/media/video/cpia2/Kconfig" config VIDEO_VINO @@ -826,6 +783,65 @@ source "drivers/media/video/cx18/Kconfig" source "drivers/media/video/saa7164/Kconfig" +# +# ISA & parallel port drivers configuration +# + +menuconfig V4L_ISA_PARPORT_DRIVERS + bool "V4L ISA and parallel port devices" + depends on ISA || PARPORT + default n + ---help--- + Say Y here to enable support for these ISA and parallel port drivers. + +if V4L_ISA_PARPORT_DRIVERS + +config VIDEO_BWQCAM + tristate "Quickcam BW Video For Linux" + depends on PARPORT && VIDEO_V4L2 + help + Say Y have if you the black and white version of the QuickCam + camera. See the next option for the color version. + + To compile this driver as a module, choose M here: the + module will be called bw-qcam. + +config VIDEO_CQCAM + tristate "QuickCam Colour Video For Linux (EXPERIMENTAL)" + depends on EXPERIMENTAL && PARPORT && VIDEO_V4L2 + help + This is the video4linux driver for the colour version of the + Connectix QuickCam. If you have one of these cameras, say Y here, + otherwise say N. This driver does not work with the original + monochrome QuickCam, QuickCam VC or QuickClip. It is also available + as a module (c-qcam). + Read for more information. + +config VIDEO_PMS + tristate "Mediavision Pro Movie Studio Video For Linux" + depends on ISA && VIDEO_V4L2 + help + Say Y if you have the ISA Mediavision Pro Movie Studio + capture card. + + To compile this driver as a module, choose M here: the + module will be called pms. + +config VIDEO_W9966 + tristate "W9966CF Webcam (FlyCam Supra and others) Video For Linux" + depends on PARPORT_1284 && PARPORT && VIDEO_V4L2 + help + Video4linux driver for Winbond's w9966 based Webcams. + Currently tested with the LifeView FlyCam Supra. + If you have one of these cameras, say Y here + otherwise say N. + This driver is also available as a module (w9966). + + Check out for more + information. + +endif # V4L_ISA_PARPORT_DRIVERS + source "drivers/media/video/marvell-ccic/Kconfig" config VIDEO_M32R_AR -- cgit v0.10.2 From 053fed7ef91206b371afbd8cb3e8cd1f27ca8bd3 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 30 Sep 2011 09:03:57 -0300 Subject: [media] V4L menu: remove the EXPERIMENTAL tag from vino and c-qcam These are really, really old drivers. These are really no longer experimental... Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig index 256ff4a..988823b 100644 --- a/drivers/media/video/Kconfig +++ b/drivers/media/video/Kconfig @@ -695,8 +695,8 @@ source "drivers/media/video/bt8xx/Kconfig" source "drivers/media/video/cpia2/Kconfig" config VIDEO_VINO - tristate "SGI Vino Video For Linux (EXPERIMENTAL)" - depends on I2C && SGI_IP22 && EXPERIMENTAL && VIDEO_V4L2 + tristate "SGI Vino Video For Linux" + depends on I2C && SGI_IP22 && VIDEO_V4L2 select VIDEO_SAA7191 if VIDEO_HELPER_CHIPS_AUTO help Say Y here to build in support for the Vino video input system found @@ -807,8 +807,8 @@ config VIDEO_BWQCAM module will be called bw-qcam. config VIDEO_CQCAM - tristate "QuickCam Colour Video For Linux (EXPERIMENTAL)" - depends on EXPERIMENTAL && PARPORT && VIDEO_V4L2 + tristate "QuickCam Colour Video For Linux" + depends on PARPORT && VIDEO_V4L2 help This is the video4linux driver for the colour version of the Connectix QuickCam. If you have one of these cameras, say Y here, -- cgit v0.10.2 From 9fa0b852e1e3c0f6abbff4e34896aabc6a555df8 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 30 Sep 2011 09:06:11 -0300 Subject: [media] V4L menu: move all platform drivers to the bottom of the menu Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig index 988823b..717a881 100644 --- a/drivers/media/video/Kconfig +++ b/drivers/media/video/Kconfig @@ -653,25 +653,6 @@ config USB_S2255 endif # V4L_USB_DRIVERS -config VIDEO_SH_VOU - tristate "SuperH VOU video output driver" - depends on VIDEO_DEV && ARCH_SHMOBILE - select VIDEOBUF_DMA_CONTIG - help - Support for the Video Output Unit (VOU) on SuperH SoCs. - -config VIDEO_VIU - tristate "Freescale VIU Video Driver" - depends on VIDEO_V4L2 && PPC_MPC512x - select VIDEOBUF_DMA_CONTIG - default y - ---help--- - Support for Freescale VIU video driver. This device captures - video data, or overlays video on DIU frame buffer. - - Say Y here if you want to enable VIU device on MPC5121e Rev2+. - In doubt, say N. - config VIDEO_VIVI tristate "Virtual Video Driver" depends on VIDEO_DEV && VIDEO_V4L2 && !SPARC32 && !SPARC64 @@ -686,22 +667,10 @@ config VIDEO_VIVI Say Y here if you want to test video apps or debug V4L devices. In doubt, say N. -source "drivers/media/video/davinci/Kconfig" - -source "drivers/media/video/omap/Kconfig" - source "drivers/media/video/bt8xx/Kconfig" source "drivers/media/video/cpia2/Kconfig" -config VIDEO_VINO - tristate "SGI Vino Video For Linux" - depends on I2C && SGI_IP22 && VIDEO_V4L2 - select VIDEO_SAA7191 if VIDEO_HELPER_CHIPS_AUTO - help - Say Y here to build in support for the Vino video input system found - on SGI Indy machines. - source "drivers/media/video/zoran/Kconfig" config VIDEO_MEYE @@ -759,16 +728,6 @@ config VIDEO_HEXIUM_GEMINI To compile this driver as a module, choose M here: the module will be called hexium_gemini. -config VIDEO_TIMBERDALE - tristate "Support for timberdale Video In/LogiWIN" - depends on VIDEO_V4L2 && I2C && DMADEVICES - select DMA_ENGINE - select TIMB_DMA - select VIDEO_ADV7180 - select VIDEOBUF_DMA_CONTIG - ---help--- - Add support for the Video In peripherial of the timberdale FPGA. - source "drivers/media/video/cx88/Kconfig" source "drivers/media/video/cx23885/Kconfig" @@ -844,6 +803,61 @@ endif # V4L_ISA_PARPORT_DRIVERS source "drivers/media/video/marvell-ccic/Kconfig" +config VIDEO_VIA_CAMERA + tristate "VIAFB camera controller support" + depends on FB_VIA + select VIDEOBUF_DMA_SG + select VIDEO_OV7670 + help + Driver support for the integrated camera controller in VIA + Chrome9 chipsets. Currently only tested on OLPC xo-1.5 systems + with ov7670 sensors. + +# +# Platform multimedia device configuration +# + +source "drivers/media/video/davinci/Kconfig" + +source "drivers/media/video/omap/Kconfig" + +config VIDEO_SH_VOU + tristate "SuperH VOU video output driver" + depends on VIDEO_DEV && ARCH_SHMOBILE + select VIDEOBUF_DMA_CONTIG + help + Support for the Video Output Unit (VOU) on SuperH SoCs. + +config VIDEO_VIU + tristate "Freescale VIU Video Driver" + depends on VIDEO_V4L2 && PPC_MPC512x + select VIDEOBUF_DMA_CONTIG + default y + ---help--- + Support for Freescale VIU video driver. This device captures + video data, or overlays video on DIU frame buffer. + + Say Y here if you want to enable VIU device on MPC5121e Rev2+. + In doubt, say N. + +config VIDEO_TIMBERDALE + tristate "Support for timberdale Video In/LogiWIN" + depends on VIDEO_V4L2 && I2C && DMADEVICES + select DMA_ENGINE + select TIMB_DMA + select VIDEO_ADV7180 + select VIDEOBUF_DMA_CONTIG + ---help--- + Add support for the Video In peripherial of the timberdale FPGA. + +config VIDEO_VINO + tristate "SGI Vino Video For Linux" + depends on I2C && SGI_IP22 && VIDEO_V4L2 + select VIDEO_SAA7191 if VIDEO_HELPER_CHIPS_AUTO + help + Say Y here to build in support for the Vino video input system found + on SGI Indy machines. + config VIDEO_M32R_AR tristate "AR devices" depends on M32R && VIDEO_V4L2 @@ -863,16 +877,6 @@ config VIDEO_M32R_AR_M64278 To compile this driver as a module, choose M here: the module will be called arv. -config VIDEO_VIA_CAMERA - tristate "VIAFB camera controller support" - depends on FB_VIA - select VIDEOBUF_DMA_SG - select VIDEO_OV7670 - help - Driver support for the integrated camera controller in VIA - Chrome9 chipsets. Currently only tested on OLPC xo-1.5 systems - with ov7670 sensors. - config VIDEO_OMAP3 tristate "OMAP 3 Camera support (EXPERIMENTAL)" depends on OMAP_IOVMM && VIDEO_V4L2 && I2C && VIDEO_V4L2_SUBDEV_API && ARCH_OMAP3 && EXPERIMENTAL -- cgit v0.10.2 From 6e66135cab8ed4ff5c1ee0dd63ff7e44e33f355f Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 30 Sep 2011 05:16:48 -0300 Subject: [media] V4L menu: remove duplicate USB dependency Thanks to Guennadi Liakhovetski for pointing this out to me. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig index 717a881..b14f5fe 100644 --- a/drivers/media/video/Kconfig +++ b/drivers/media/video/Kconfig @@ -589,7 +589,7 @@ menuconfig V4L_USB_DRIVERS depends on USB default y -if V4L_USB_DRIVERS && USB +if V4L_USB_DRIVERS source "drivers/media/video/uvc/Kconfig" -- cgit v0.10.2 From e21d98651ae42dc7c50e539296e88a73c1e78fd8 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 30 Sep 2011 05:31:24 -0300 Subject: [media] V4L menu: reorganize the radio menu Move all USB radio devices to the top of the list and move all ISA devices to a separate menu. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/radio/Kconfig b/drivers/media/radio/Kconfig index 52798a1..e954781 100644 --- a/drivers/media/radio/Kconfig +++ b/drivers/media/radio/Kconfig @@ -11,6 +11,162 @@ menuconfig RADIO_ADAPTERS if RADIO_ADAPTERS && VIDEO_V4L2 +config RADIO_SI470X + bool "Silicon Labs Si470x FM Radio Receiver support" + depends on VIDEO_V4L2 + +source "drivers/media/radio/si470x/Kconfig" + +config USB_MR800 + tristate "AverMedia MR 800 USB FM radio support" + depends on USB && VIDEO_V4L2 + ---help--- + Say Y here if you want to connect this type of radio to your + computer's USB port. Note that the audio is not digital, and + you must connect the line out connector to a sound card or a + set of speakers. + + To compile this driver as a module, choose M here: the + module will be called radio-mr800. + +config USB_DSBR + tristate "D-Link/GemTek USB FM radio support" + depends on USB && VIDEO_V4L2 + ---help--- + Say Y here if you want to connect this type of radio to your + computer's USB port. Note that the audio is not digital, and + you must connect the line out connector to a sound card or a + set of speakers. + + To compile this driver as a module, choose M here: the + module will be called dsbr100. + +config RADIO_MAXIRADIO + tristate "Guillemot MAXI Radio FM 2000 radio" + depends on VIDEO_V4L2 && PCI + ---help--- + Choose Y here if you have this radio card. This card may also be + found as Gemtek PCI FM. + + In order to control your radio card, you will need to use programs + that are compatible with the Video For Linux API. Information on + this API and pointers to "v4l" programs may be found at + . + + To compile this driver as a module, choose M here: the + module will be called radio-maxiradio. + + +config I2C_SI4713 + tristate "I2C driver for Silicon Labs Si4713 device" + depends on I2C && VIDEO_V4L2 + ---help--- + Say Y here if you want support to Si4713 I2C device. + This device driver supports only i2c bus. + + To compile this driver as a module, choose M here: the + module will be called si4713. + +config RADIO_SI4713 + tristate "Silicon Labs Si4713 FM Radio Transmitter support" + depends on I2C && VIDEO_V4L2 + select I2C_SI4713 + ---help--- + Say Y here if you want support to Si4713 FM Radio Transmitter. + This device can transmit audio through FM. It can transmit + RDS and RBDS signals as well. This module is the v4l2 radio + interface for the i2c driver of this device. + + To compile this driver as a module, choose M here: the + module will be called radio-si4713. + +config RADIO_TEA5764 + tristate "TEA5764 I2C FM radio support" + depends on I2C && VIDEO_V4L2 + ---help--- + Say Y here if you want to use the TEA5764 FM chip found in + EZX phones. This FM chip is present in EZX phones from Motorola, + connected to internal pxa I2C bus. + + To compile this driver as a module, choose M here: the + module will be called radio-tea5764. + +config RADIO_TEA5764_XTAL + bool "TEA5764 crystal reference" + depends on RADIO_TEA5764=y + default y + help + Say Y here if TEA5764 have a 32768 Hz crystal in circuit, say N + here if TEA5764 reference frequency is connected in FREQIN. + +config RADIO_SAA7706H + tristate "SAA7706H Car Radio DSP" + depends on I2C && VIDEO_V4L2 + ---help--- + Say Y here if you want to use the SAA7706H Car radio Digital + Signal Processor, found for instance on the Russellville development + board. On the russellville the device is connected to internal + timberdale I2C bus. + + To compile this driver as a module, choose M here: the + module will be called SAA7706H. + +config RADIO_TEF6862 + tristate "TEF6862 Car Radio Enhanced Selectivity Tuner" + depends on I2C && VIDEO_V4L2 + ---help--- + Say Y here if you want to use the TEF6862 Car Radio Enhanced + Selectivity Tuner, found for instance on the Russellville development + board. On the russellville the device is connected to internal + timberdale I2C bus. + + To compile this driver as a module, choose M here: the + module will be called TEF6862. + +config RADIO_TIMBERDALE + tristate "Enable the Timberdale radio driver" + depends on MFD_TIMBERDALE && VIDEO_V4L2 + depends on I2C # for RADIO_SAA7706H + select RADIO_TEF6862 + select RADIO_SAA7706H + ---help--- + This is a kind of umbrella driver for the Radio Tuner and DSP + found behind the Timberdale FPGA on the Russellville board. + Enabling this driver will automatically select the DSP and tuner. + +config RADIO_WL1273 + tristate "Texas Instruments WL1273 I2C FM Radio" + depends on I2C && VIDEO_V4L2 + select MFD_CORE + select MFD_WL1273_CORE + select FW_LOADER + ---help--- + Choose Y here if you have this FM radio chip. + + In order to control your radio card, you will need to use programs + that are compatible with the Video For Linux 2 API. Information on + this API and pointers to "v4l2" programs may be found at + . + + To compile this driver as a module, choose M here: the + module will be called radio-wl1273. + +# TI's ST based wl128x FM radio +source "drivers/media/radio/wl128x/Kconfig" + +# +# ISA drivers configuration +# + +menuconfig V4L_RADIO_ISA_DRIVERS + bool "ISA radio devices" + depends on ISA + default n + ---help--- + Say Y here to enable support for these ISA drivers. + +if V4L_RADIO_ISA_DRIVERS + config RADIO_CADET tristate "ADS Cadet AM/FM Tuner" depends on ISA && VIDEO_V4L2 @@ -151,21 +307,6 @@ config RADIO_GEMTEK_PROBE following ports will be probed: 0x20c, 0x30c, 0x24c, 0x34c, 0x248 and 0x28c. -config RADIO_MAXIRADIO - tristate "Guillemot MAXI Radio FM 2000 radio" - depends on VIDEO_V4L2 && PCI - ---help--- - Choose Y here if you have this radio card. This card may also be - found as Gemtek PCI FM. - - In order to control your radio card, you will need to use programs - that are compatible with the Video For Linux API. Information on - this API and pointers to "v4l" programs may be found at - . - - To compile this driver as a module, choose M here: the - module will be called radio-maxiradio. - config RADIO_MIROPCM20 tristate "miroSOUND PCM20 radio" depends on ISA && ISA_DMA_API && VIDEO_V4L2 && SND @@ -316,131 +457,6 @@ config RADIO_ZOLTRIX_PORT help Enter the I/O port of your Zoltrix radio card. -config I2C_SI4713 - tristate "I2C driver for Silicon Labs Si4713 device" - depends on I2C && VIDEO_V4L2 - ---help--- - Say Y here if you want support to Si4713 I2C device. - This device driver supports only i2c bus. - - To compile this driver as a module, choose M here: the - module will be called si4713. - -config RADIO_SI4713 - tristate "Silicon Labs Si4713 FM Radio Transmitter support" - depends on I2C && VIDEO_V4L2 - select I2C_SI4713 - ---help--- - Say Y here if you want support to Si4713 FM Radio Transmitter. - This device can transmit audio through FM. It can transmit - RDS and RBDS signals as well. This module is the v4l2 radio - interface for the i2c driver of this device. - - To compile this driver as a module, choose M here: the - module will be called radio-si4713. - -config USB_DSBR - tristate "D-Link/GemTek USB FM radio support" - depends on USB && VIDEO_V4L2 - ---help--- - Say Y here if you want to connect this type of radio to your - computer's USB port. Note that the audio is not digital, and - you must connect the line out connector to a sound card or a - set of speakers. - - To compile this driver as a module, choose M here: the - module will be called dsbr100. - -config RADIO_SI470X - bool "Silicon Labs Si470x FM Radio Receiver support" - depends on VIDEO_V4L2 - -source "drivers/media/radio/si470x/Kconfig" - -config USB_MR800 - tristate "AverMedia MR 800 USB FM radio support" - depends on USB && VIDEO_V4L2 - ---help--- - Say Y here if you want to connect this type of radio to your - computer's USB port. Note that the audio is not digital, and - you must connect the line out connector to a sound card or a - set of speakers. - - To compile this driver as a module, choose M here: the - module will be called radio-mr800. - -config RADIO_TEA5764 - tristate "TEA5764 I2C FM radio support" - depends on I2C && VIDEO_V4L2 - ---help--- - Say Y here if you want to use the TEA5764 FM chip found in - EZX phones. This FM chip is present in EZX phones from Motorola, - connected to internal pxa I2C bus. - - To compile this driver as a module, choose M here: the - module will be called radio-tea5764. - -config RADIO_TEA5764_XTAL - bool "TEA5764 crystal reference" - depends on RADIO_TEA5764=y - default y - help - Say Y here if TEA5764 have a 32768 Hz crystal in circuit, say N - here if TEA5764 reference frequency is connected in FREQIN. - -config RADIO_SAA7706H - tristate "SAA7706H Car Radio DSP" - depends on I2C && VIDEO_V4L2 - ---help--- - Say Y here if you want to use the SAA7706H Car radio Digital - Signal Processor, found for instance on the Russellville development - board. On the russellville the device is connected to internal - timberdale I2C bus. - - To compile this driver as a module, choose M here: the - module will be called SAA7706H. - -config RADIO_TEF6862 - tristate "TEF6862 Car Radio Enhanced Selectivity Tuner" - depends on I2C && VIDEO_V4L2 - ---help--- - Say Y here if you want to use the TEF6862 Car Radio Enhanced - Selectivity Tuner, found for instance on the Russellville development - board. On the russellville the device is connected to internal - timberdale I2C bus. - - To compile this driver as a module, choose M here: the - module will be called TEF6862. - -config RADIO_TIMBERDALE - tristate "Enable the Timberdale radio driver" - depends on MFD_TIMBERDALE && VIDEO_V4L2 - depends on I2C # for RADIO_SAA7706H - select RADIO_TEF6862 - select RADIO_SAA7706H - ---help--- - This is a kind of umbrella driver for the Radio Tuner and DSP - found behind the Timberdale FPGA on the Russellville board. - Enabling this driver will automatically select the DSP and tuner. - -config RADIO_WL1273 - tristate "Texas Instruments WL1273 I2C FM Radio" - depends on I2C && VIDEO_V4L2 - select MFD_CORE - select MFD_WL1273_CORE - select FW_LOADER - ---help--- - Choose Y here if you have this FM radio chip. - - In order to control your radio card, you will need to use programs - that are compatible with the Video For Linux 2 API. Information on - this API and pointers to "v4l2" programs may be found at - . - - To compile this driver as a module, choose M here: the - module will be called radio-wl1273. - -# TI's ST based wl128x FM radio -source "drivers/media/radio/wl128x/Kconfig" +endif # V4L_RADIO_ISA_DRIVERS endif # RADIO_ADAPTERS -- cgit v0.10.2 From 486eeb5628f812b4836405e2b2e76594287dd873 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 30 Sep 2011 09:14:19 -0300 Subject: [media] V4L menu: move all PCI(e) devices to their own submenu Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig index b14f5fe..b43366a 100644 --- a/drivers/media/video/Kconfig +++ b/drivers/media/video/Kconfig @@ -580,6 +580,20 @@ config VIDEO_M52790 endmenu # encoder / decoder chips +config VIDEO_VIVI + tristate "Virtual Video Driver" + depends on VIDEO_DEV && VIDEO_V4L2 && !SPARC32 && !SPARC64 + depends on FRAMEBUFFER_CONSOLE || STI_CONSOLE + select FONT_8x16 + select VIDEOBUF2_VMALLOC + default n + ---help--- + Enables a virtual video driver. This device shows a color bar + and a timestamp, as a real device would generate by using V4L2 + api. + Say Y here if you want to test video apps or debug V4L devices. + In doubt, say N. + # # USB Multimedia device configuration # @@ -615,6 +629,8 @@ source "drivers/media/video/sn9c102/Kconfig" source "drivers/media/video/pwc/Kconfig" +source "drivers/media/video/cpia2/Kconfig" + config USB_ZR364XX tristate "USB ZR364XX Camera support" depends on VIDEO_V4L2 @@ -653,25 +669,55 @@ config USB_S2255 endif # V4L_USB_DRIVERS -config VIDEO_VIVI - tristate "Virtual Video Driver" - depends on VIDEO_DEV && VIDEO_V4L2 && !SPARC32 && !SPARC64 - depends on FRAMEBUFFER_CONSOLE || STI_CONSOLE - select FONT_8x16 - select VIDEOBUF2_VMALLOC - default n +# +# PCI drivers configuration +# + +menuconfig V4L_PCI_DRIVERS + bool "V4L PCI(e) devices" + depends on PCI + default y ---help--- - Enables a virtual video driver. This device shows a color bar - and a timestamp, as a real device would generate by using V4L2 - api. - Say Y here if you want to test video apps or debug V4L devices. - In doubt, say N. + Say Y here to enable support for these PCI(e) drivers. + +if V4L_PCI_DRIVERS + +source "drivers/media/video/au0828/Kconfig" source "drivers/media/video/bt8xx/Kconfig" -source "drivers/media/video/cpia2/Kconfig" +source "drivers/media/video/cx18/Kconfig" -source "drivers/media/video/zoran/Kconfig" +source "drivers/media/video/cx23885/Kconfig" + +source "drivers/media/video/cx25821/Kconfig" + +source "drivers/media/video/cx88/Kconfig" + +config VIDEO_HEXIUM_GEMINI + tristate "Hexium Gemini frame grabber" + depends on PCI && VIDEO_V4L2 && I2C + select VIDEO_SAA7146_VV + ---help--- + This is a video4linux driver for the Hexium Gemini frame + grabber card by Hexium. Please note that the Gemini Dual + card is *not* fully supported. + + To compile this driver as a module, choose M here: the + module will be called hexium_gemini. + +config VIDEO_HEXIUM_ORION + tristate "Hexium HV-PCI6 and Orion frame grabber" + depends on PCI && VIDEO_V4L2 && I2C + select VIDEO_SAA7146_VV + ---help--- + This is a video4linux driver for the Hexium HV-PCI6 and + Orion frame grabber cards by Hexium. + + To compile this driver as a module, choose M here: the + module will be called hexium_orion. + +source "drivers/media/video/ivtv/Kconfig" config VIDEO_MEYE tristate "Sony Vaio Picturebook Motion Eye Video For Linux" @@ -687,8 +733,6 @@ config VIDEO_MEYE To compile this driver as a module, choose M here: the module will be called meye. -source "drivers/media/video/saa7134/Kconfig" - config VIDEO_MXB tristate "Siemens-Nixdorf 'Multimedia eXtension Board'" depends on PCI && VIDEO_V4L2 && I2C @@ -705,42 +749,13 @@ config VIDEO_MXB To compile this driver as a module, choose M here: the module will be called mxb. -config VIDEO_HEXIUM_ORION - tristate "Hexium HV-PCI6 and Orion frame grabber" - depends on PCI && VIDEO_V4L2 && I2C - select VIDEO_SAA7146_VV - ---help--- - This is a video4linux driver for the Hexium HV-PCI6 and - Orion frame grabber cards by Hexium. - - To compile this driver as a module, choose M here: the - module will be called hexium_orion. - -config VIDEO_HEXIUM_GEMINI - tristate "Hexium Gemini frame grabber" - depends on PCI && VIDEO_V4L2 && I2C - select VIDEO_SAA7146_VV - ---help--- - This is a video4linux driver for the Hexium Gemini frame - grabber card by Hexium. Please note that the Gemini Dual - card is *not* fully supported. - - To compile this driver as a module, choose M here: the - module will be called hexium_gemini. - -source "drivers/media/video/cx88/Kconfig" - -source "drivers/media/video/cx23885/Kconfig" - -source "drivers/media/video/cx25821/Kconfig" - -source "drivers/media/video/au0828/Kconfig" +source "drivers/media/video/saa7134/Kconfig" -source "drivers/media/video/ivtv/Kconfig" +source "drivers/media/video/saa7164/Kconfig" -source "drivers/media/video/cx18/Kconfig" +source "drivers/media/video/zoran/Kconfig" -source "drivers/media/video/saa7164/Kconfig" +endif # V4L_PCI_DRIVERS # # ISA & parallel port drivers configuration -- cgit v0.10.2 From 1df3a2c6d036f4923c229fa98725deda320680e1 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Mon, 7 Nov 2011 06:26:59 -0300 Subject: [media] cx88: fix menu level for the VP-3054 module Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/cx88/Kconfig b/drivers/media/video/cx88/Kconfig index 5c42abd..3598dc0 100644 --- a/drivers/media/video/cx88/Kconfig +++ b/drivers/media/video/cx88/Kconfig @@ -70,11 +70,6 @@ config VIDEO_CX88_DVB To compile this driver as a module, choose M here: the module will be called cx88-dvb. -config VIDEO_CX88_MPEG - tristate - depends on VIDEO_CX88_DVB || VIDEO_CX88_BLACKBIRD - default y - config VIDEO_CX88_VP3054 tristate "VP-3054 Secondary I2C Bus Support" default m @@ -84,3 +79,8 @@ config VIDEO_CX88_VP3054 Conexant 2388x chip and the MT352 demodulator, which also require support for the VP-3054 Secondary I2C bus, such at DNTV Live! DVB-T Pro. + +config VIDEO_CX88_MPEG + tristate + depends on VIDEO_CX88_DVB || VIDEO_CX88_BLACKBIRD + default y -- cgit v0.10.2 From e9eb0dadba932940f721f9d27544a7818b2fa1c5 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Tue, 8 Nov 2011 11:02:34 -0300 Subject: [media] V4L menu: add submenu for platform devices Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig index b43366a..4e8a0c4 100644 --- a/drivers/media/video/Kconfig +++ b/drivers/media/video/Kconfig @@ -816,6 +816,14 @@ config VIDEO_W9966 endif # V4L_ISA_PARPORT_DRIVERS +menuconfig V4L_PLATFORM_DRIVERS + bool "V4L platform devices" + default n + ---help--- + Say Y here to enable support for platform-specific V4L drivers. + +if V4L_PLATFORM_DRIVERS + source "drivers/media/video/marvell-ccic/Kconfig" config VIDEO_VIA_CAMERA @@ -1110,6 +1118,7 @@ config VIDEO_S5P_MIPI_CSIS source "drivers/media/video/s5p-tv/Kconfig" +endif # V4L_PLATFORM_DRIVERS endif # VIDEO_CAPTURE_DRIVERS menuconfig V4L_MEM2MEM_DRIVERS -- cgit v0.10.2 From 16bfdaafa2c66d8cc81422a97a105a849ca65b3e Mon Sep 17 00:00:00 2001 From: "J. Bruce Fields" Date: Mon, 7 Nov 2011 17:23:30 -0500 Subject: nfsd4: share open and lock owner hash tables Now that they're used in the same way, it's a little simpler to put open and lock owners in the same hash table, and I can't see a reason not to. Signed-off-by: J. Bruce Fields diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index eec9900..dcbe7f3 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -133,21 +133,21 @@ unsigned int max_delegations; * Open owner state (share locks) */ -/* hash tables for open owners */ -#define OPEN_OWNER_HASH_BITS 8 -#define OPEN_OWNER_HASH_SIZE (1 << OPEN_OWNER_HASH_BITS) -#define OPEN_OWNER_HASH_MASK (OPEN_OWNER_HASH_SIZE - 1) +/* hash tables for lock and open owners */ +#define OWNER_HASH_BITS 8 +#define OWNER_HASH_SIZE (1 << OWNER_HASH_BITS) +#define OWNER_HASH_MASK (OWNER_HASH_SIZE - 1) -static unsigned int open_ownerstr_hashval(u32 clientid, struct xdr_netobj *ownername) +static unsigned int ownerstr_hashval(u32 clientid, struct xdr_netobj *ownername) { unsigned int ret; ret = opaque_hashval(ownername->data, ownername->len); ret += clientid; - return ret & OPEN_OWNER_HASH_MASK; + return ret & OWNER_HASH_MASK; } -static struct list_head open_ownerstr_hashtbl[OPEN_OWNER_HASH_SIZE]; +static struct list_head ownerstr_hashtbl[OWNER_HASH_SIZE]; /* hash table for nfs4_file */ #define FILE_HASH_BITS 8 @@ -2373,7 +2373,7 @@ static inline void *alloc_stateowner(struct kmem_cache *slab, struct xdr_netobj static void hash_openowner(struct nfs4_openowner *oo, struct nfs4_client *clp, unsigned int strhashval) { - list_add(&oo->oo_owner.so_strhash, &open_ownerstr_hashtbl[strhashval]); + list_add(&oo->oo_owner.so_strhash, &ownerstr_hashtbl[strhashval]); list_add(&oo->oo_perclient, &clp->cl_openowners); } @@ -2436,7 +2436,9 @@ find_openstateowner_str(unsigned int hashval, struct nfsd4_open *open) struct nfs4_stateowner *so; struct nfs4_openowner *oo; - list_for_each_entry(so, &open_ownerstr_hashtbl[hashval], so_strhash) { + list_for_each_entry(so, &ownerstr_hashtbl[hashval], so_strhash) { + if (!so->so_is_open_owner) + continue; if (same_owner_str(so, &open->op_owner, &open->op_clientid)) { oo = openowner(so); renew_client(oo->oo_owner.so_client); @@ -2580,7 +2582,7 @@ nfsd4_process_open1(struct nfsd4_compound_state *cstate, if (open->op_file == NULL) return nfserr_jukebox; - strhashval = open_ownerstr_hashval(clientid->cl_id, &open->op_owner); + strhashval = ownerstr_hashval(clientid->cl_id, &open->op_owner); oo = find_openstateowner_str(strhashval, open); open->op_openowner = oo; if (!oo) { @@ -3718,13 +3720,7 @@ out: } -/* - * Lock owner state (byte-range locks) - */ #define LOFF_OVERFLOW(start, len) ((u64)(len) > ~(u64)(start)) -#define LOCK_HASH_BITS 8 -#define LOCK_HASH_SIZE (1 << LOCK_HASH_BITS) -#define LOCK_HASH_MASK (LOCK_HASH_SIZE - 1) static inline u64 end_offset(u64 start, u64 len) @@ -3746,8 +3742,6 @@ last_byte_offset(u64 start, u64 len) return end > start ? end - 1: NFS4_MAX_UINT64; } -static struct list_head lock_ownerstr_hashtbl[LOCK_HASH_SIZE]; - /* * TODO: Linux file offsets are _signed_ 64-bit quantities, which means that * we can't properly handle lock requests that go beyond the (2^63 - 1)-th @@ -3815,11 +3809,13 @@ static struct nfs4_lockowner * find_lockowner_str(struct inode *inode, clientid_t *clid, struct xdr_netobj *owner) { - unsigned int hashval = open_ownerstr_hashval(clid->cl_id, owner); + unsigned int hashval = ownerstr_hashval(clid->cl_id, owner); struct nfs4_lockowner *lo; struct nfs4_stateowner *op; - list_for_each_entry(op, &lock_ownerstr_hashtbl[hashval], so_strhash) { + list_for_each_entry(op, &ownerstr_hashtbl[hashval], so_strhash) { + if (op->so_is_open_owner) + continue; lo = lockowner(op); if (same_lockowner_ino(lo, inode, clid, owner)) return lo; @@ -3829,7 +3825,7 @@ find_lockowner_str(struct inode *inode, clientid_t *clid, static void hash_lockowner(struct nfs4_lockowner *lo, unsigned int strhashval, struct nfs4_client *clp, struct nfs4_ol_stateid *open_stp) { - list_add(&lo->lo_owner.so_strhash, &lock_ownerstr_hashtbl[strhashval]); + list_add(&lo->lo_owner.so_strhash, &ownerstr_hashtbl[strhashval]); list_add(&lo->lo_perstateid, &open_stp->st_lockowners); } @@ -3838,7 +3834,7 @@ static void hash_lockowner(struct nfs4_lockowner *lo, unsigned int strhashval, s * Called in nfsd4_lock - therefore, OPEN and OPEN_CONFIRM (if needed) has * occurred. * - * strhashval = open_ownerstr_hashval + * strhashval = ownerstr_hashval */ static struct nfs4_lockowner * @@ -3913,7 +3909,7 @@ __be32 lookup_or_create_lock_state(struct nfsd4_compound_state *cstate, struct n struct nfs4_ol_stateid, st_perstateowner); return nfs_ok; } - strhashval = open_ownerstr_hashval(cl->cl_clientid.cl_id, + strhashval = ownerstr_hashval(cl->cl_clientid.cl_id, &lock->v.new.owner); lo = alloc_init_lock_stateowner(strhashval, cl, ost, lock); if (lo == NULL) @@ -4277,7 +4273,7 @@ nfsd4_release_lockowner(struct svc_rqst *rqstp, struct nfs4_ol_stateid *stp; struct xdr_netobj *owner = &rlockowner->rl_owner; struct list_head matches; - unsigned int hashval = open_ownerstr_hashval(clid->cl_id, owner); + unsigned int hashval = ownerstr_hashval(clid->cl_id, owner); __be32 status; dprintk("nfsd4_release_lockowner clientid: (%08x/%08x):\n", @@ -4294,7 +4290,9 @@ nfsd4_release_lockowner(struct svc_rqst *rqstp, status = nfserr_locks_held; INIT_LIST_HEAD(&matches); - list_for_each_entry(sop, &lock_ownerstr_hashtbl[hashval], so_strhash) { + list_for_each_entry(sop, &ownerstr_hashtbl[hashval], so_strhash) { + if (sop->so_is_open_owner) + continue; if (!same_owner_str(sop, owner, clid)) continue; list_for_each_entry(stp, &sop->so_stateids, @@ -4444,16 +4442,16 @@ static void release_openowner_sop(struct nfs4_stateowner *sop) release_openowner(openowner(sop)); } -static int nfsd_release_n_owners(u64 num, - struct list_head hashtbl[], - unsigned int hashtbl_size, +static int nfsd_release_n_owners(u64 num, bool is_open_owner void (*release_sop)(struct nfs4_stateowner *)) { int i, count = 0; struct nfs4_stateowner *sop, *next; - for (i = 0; i < hashtbl_size; i++) { - list_for_each_entry_safe(sop, next, &hashtbl[i], so_strhash) { + for (i = 0; i < OWNER_HASH_SIZE; i++) { + list_for_each_entry_safe(sop, next, &ownerstr_hashtbl[i], so_strhash) { + if (sop->so_is_open_owner != is_open_owner) + continue; release_sop(sop); if (++count == num) return count; @@ -4467,8 +4465,7 @@ void nfsd_forget_locks(u64 num) int count; nfs4_lock_state(); - count = nfsd_release_n_owners(num, lock_ownerstr_hashtbl, - LOCK_HASH_SIZE, release_lockowner_sop); + count = nfsd_release_n_owners(num, false, release_lockowner_sop); nfs4_unlock_state(); printk(KERN_INFO "NFSD: Forgot %d locks", count); @@ -4479,8 +4476,7 @@ void nfsd_forget_openowners(u64 num) int count; nfs4_lock_state(); - count = nfsd_release_n_owners(num, open_ownerstr_hashtbl, - OPEN_OWNER_HASH_SIZE, release_openowner_sop); + count = nfsd_release_n_owners(num, true, release_openowner_sop); nfs4_unlock_state(); printk(KERN_INFO "NFSD: Forgot %d open owners", count); @@ -4549,11 +4545,8 @@ nfs4_state_init(void) for (i = 0; i < FILE_HASH_SIZE; i++) { INIT_LIST_HEAD(&file_hashtbl[i]); } - for (i = 0; i < OPEN_OWNER_HASH_SIZE; i++) { - INIT_LIST_HEAD(&open_ownerstr_hashtbl[i]); - } - for (i = 0; i < LOCK_HASH_SIZE; i++) { - INIT_LIST_HEAD(&lock_ownerstr_hashtbl[i]); + for (i = 0; i < OWNER_HASH_SIZE; i++) { + INIT_LIST_HEAD(&ownerstr_hashtbl[i]); } memset(&onestateid, ~0, sizeof(stateid_t)); INIT_LIST_HEAD(&close_lru); -- cgit v0.10.2 From 39ce61a846c8e1fa00cb57ad5af021542e6e8403 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 11 Nov 2011 12:46:23 -0200 Subject: [media] dvb: Allow select between DVB-C Annex A and Annex C DVB-C, as defined by ITU-T J.83 has 3 annexes. The differences between Annex A and Annex C is that Annex C uses a subset of the modulation types, and uses a different rolloff factor. A different rolloff means that the bandwidth required is slicely different, and may affect the saw filter configuration at the tuners. Also, some demods have different configurations, depending on using Annex A or Annex C. So, allow userspace to specify it, by changing the rolloff factor. Signed-off-by: Mauro Carvalho Chehab diff --git a/Documentation/DocBook/media/dvb/dvbproperty.xml b/Documentation/DocBook/media/dvb/dvbproperty.xml index 3bc8a61..6ac8039 100644 --- a/Documentation/DocBook/media/dvb/dvbproperty.xml +++ b/Documentation/DocBook/media/dvb/dvbproperty.xml @@ -311,6 +311,8 @@ typedef enum fe_rolloff { ROLLOFF_20, ROLLOFF_25, ROLLOFF_AUTO, + ROLLOFF_15, /* DVB-C Annex A */ + ROLLOFF_13, /* DVB-C Annex C */ } fe_rolloff_t; @@ -778,8 +780,10 @@ typedef enum fe_hierarchy { DTV_MODULATION DTV_INVERSION DTV_SYMBOL_RATE + DTV_ROLLOFF DTV_INNER_FEC + The Rolloff of 0.15 (ROLLOFF_15) is assumed, as ITU-T J.83 Annex A is more common. For Annex C, rolloff should be 0.13 (ROLLOFF_13). All other values are invalid.
DVB-C Annex B delivery system diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c index 2c0acdb..c849455 100644 --- a/drivers/media/dvb/dvb-core/dvb_frontend.c +++ b/drivers/media/dvb/dvb-core/dvb_frontend.c @@ -876,6 +876,7 @@ static int dvb_frontend_clear_cache(struct dvb_frontend *fe) c->symbol_rate = QAM_AUTO; c->code_rate_HP = FEC_AUTO; c->code_rate_LP = FEC_AUTO; + c->rolloff = ROLLOFF_AUTO; c->isdbt_partial_reception = -1; c->isdbt_sb_mode = -1; @@ -1030,6 +1031,7 @@ static void dtv_property_cache_init(struct dvb_frontend *fe, break; case FE_QAM: c->delivery_system = SYS_DVBC_ANNEX_AC; + c->rolloff = ROLLOFF_15; /* implied for Annex A */ break; case FE_OFDM: c->delivery_system = SYS_DVBT; diff --git a/include/linux/dvb/frontend.h b/include/linux/dvb/frontend.h index 1b1094c..d9251df 100644 --- a/include/linux/dvb/frontend.h +++ b/include/linux/dvb/frontend.h @@ -329,6 +329,8 @@ typedef enum fe_rolloff { ROLLOFF_20, ROLLOFF_25, ROLLOFF_AUTO, + ROLLOFF_15, /* DVB-C Annex A */ + ROLLOFF_13, /* DVB-C Annex C */ } fe_rolloff_t; typedef enum fe_delivery_system { -- cgit v0.10.2 From 5a6b5e02d673486c96003d4a6e3e2510f4c59f92 Mon Sep 17 00:00:00 2001 From: Florian Tobias Schandinat Date: Sat, 3 Sep 2011 01:36:08 +0000 Subject: fbdev: remove display subsystem This four year old subsystem does not have a single in-tree user not even in staging and as far as I know also none out-of-tree. I think that justifies removing it which cleans the config up. Signed-off-by: Florian Tobias Schandinat Acked-by: James Simmons Cc: Andrew Morton diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index 8165c55..1b5b98f 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig @@ -2413,7 +2413,6 @@ source "drivers/video/omap/Kconfig" source "drivers/video/omap2/Kconfig" source "drivers/video/backlight/Kconfig" -source "drivers/video/display/Kconfig" if VT source "drivers/video/console/Kconfig" diff --git a/drivers/video/Makefile b/drivers/video/Makefile index 9b9d8ff..1426068 100644 --- a/drivers/video/Makefile +++ b/drivers/video/Makefile @@ -13,7 +13,7 @@ fb-objs := $(fb-y) obj-$(CONFIG_VT) += console/ obj-$(CONFIG_LOGO) += logo/ -obj-y += backlight/ display/ +obj-y += backlight/ obj-$(CONFIG_FB_CFB_FILLRECT) += cfbfillrect.o obj-$(CONFIG_FB_CFB_COPYAREA) += cfbcopyarea.o diff --git a/drivers/video/display/Kconfig b/drivers/video/display/Kconfig deleted file mode 100644 index f99af93..0000000 --- a/drivers/video/display/Kconfig +++ /dev/null @@ -1,24 +0,0 @@ -# -# Display drivers configuration -# - -menu "Display device support" - -config DISPLAY_SUPPORT - tristate "Display panel/monitor support" - ---help--- - This framework adds support for low-level control of a display. - This includes support for power. - - Enable this to be able to choose the drivers for controlling the - physical display panel/monitor on some platforms. This not only - covers LCD displays for PDAs but also other types of displays - such as CRT, TVout etc. - - To have support for your specific display panel you will have to - select the proper drivers which depend on this option. - -comment "Display hardware drivers" - depends on DISPLAY_SUPPORT - -endmenu diff --git a/drivers/video/display/Makefile b/drivers/video/display/Makefile deleted file mode 100644 index c0ea832..0000000 --- a/drivers/video/display/Makefile +++ /dev/null @@ -1,6 +0,0 @@ -# Display drivers - -display-objs := display-sysfs.o - -obj-$(CONFIG_DISPLAY_SUPPORT) += display.o - diff --git a/drivers/video/display/display-sysfs.c b/drivers/video/display/display-sysfs.c deleted file mode 100644 index 0c647d7..0000000 --- a/drivers/video/display/display-sysfs.c +++ /dev/null @@ -1,219 +0,0 @@ -/* - * display-sysfs.c - Display output driver sysfs interface - * - * Copyright (C) 2007 James Simmons - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or (at - * your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - */ -#include -#include -#include -#include -#include -#include -#include - -static ssize_t display_show_name(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct display_device *dsp = dev_get_drvdata(dev); - return snprintf(buf, PAGE_SIZE, "%s\n", dsp->name); -} - -static ssize_t display_show_type(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct display_device *dsp = dev_get_drvdata(dev); - return snprintf(buf, PAGE_SIZE, "%s\n", dsp->type); -} - -static ssize_t display_show_contrast(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct display_device *dsp = dev_get_drvdata(dev); - ssize_t rc = -ENXIO; - - mutex_lock(&dsp->lock); - if (likely(dsp->driver) && dsp->driver->get_contrast) - rc = sprintf(buf, "%d\n", dsp->driver->get_contrast(dsp)); - mutex_unlock(&dsp->lock); - return rc; -} - -static ssize_t display_store_contrast(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - struct display_device *dsp = dev_get_drvdata(dev); - ssize_t ret = -EINVAL, size; - int contrast; - char *endp; - - contrast = simple_strtoul(buf, &endp, 0); - size = endp - buf; - - if (isspace(*endp)) - size++; - - if (size != count) - return ret; - - mutex_lock(&dsp->lock); - if (likely(dsp->driver && dsp->driver->set_contrast)) { - pr_debug("display: set contrast to %d\n", contrast); - dsp->driver->set_contrast(dsp, contrast); - ret = count; - } - mutex_unlock(&dsp->lock); - return ret; -} - -static ssize_t display_show_max_contrast(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct display_device *dsp = dev_get_drvdata(dev); - ssize_t rc = -ENXIO; - - mutex_lock(&dsp->lock); - if (likely(dsp->driver)) - rc = sprintf(buf, "%d\n", dsp->driver->max_contrast); - mutex_unlock(&dsp->lock); - return rc; -} - -static struct device_attribute display_attrs[] = { - __ATTR(name, S_IRUGO, display_show_name, NULL), - __ATTR(type, S_IRUGO, display_show_type, NULL), - __ATTR(contrast, S_IRUGO | S_IWUSR, display_show_contrast, display_store_contrast), - __ATTR(max_contrast, S_IRUGO, display_show_max_contrast, NULL), -}; - -static int display_suspend(struct device *dev, pm_message_t state) -{ - struct display_device *dsp = dev_get_drvdata(dev); - - mutex_lock(&dsp->lock); - if (likely(dsp->driver->suspend)) - dsp->driver->suspend(dsp, state); - mutex_unlock(&dsp->lock); - return 0; -}; - -static int display_resume(struct device *dev) -{ - struct display_device *dsp = dev_get_drvdata(dev); - - mutex_lock(&dsp->lock); - if (likely(dsp->driver->resume)) - dsp->driver->resume(dsp); - mutex_unlock(&dsp->lock); - return 0; -}; - -static struct mutex allocated_dsp_lock; -static DEFINE_IDR(allocated_dsp); -static struct class *display_class; - -struct display_device *display_device_register(struct display_driver *driver, - struct device *parent, void *devdata) -{ - struct display_device *new_dev = NULL; - int ret = -EINVAL; - - if (unlikely(!driver)) - return ERR_PTR(ret); - - mutex_lock(&allocated_dsp_lock); - ret = idr_pre_get(&allocated_dsp, GFP_KERNEL); - mutex_unlock(&allocated_dsp_lock); - if (!ret) - return ERR_PTR(ret); - - new_dev = kzalloc(sizeof(struct display_device), GFP_KERNEL); - if (likely(new_dev) && unlikely(driver->probe(new_dev, devdata))) { - // Reserve the index for this display - mutex_lock(&allocated_dsp_lock); - ret = idr_get_new(&allocated_dsp, new_dev, &new_dev->idx); - mutex_unlock(&allocated_dsp_lock); - - if (!ret) { - new_dev->dev = device_create(display_class, parent, - MKDEV(0, 0), new_dev, - "display%d", new_dev->idx); - if (!IS_ERR(new_dev->dev)) { - new_dev->parent = parent; - new_dev->driver = driver; - mutex_init(&new_dev->lock); - return new_dev; - } - mutex_lock(&allocated_dsp_lock); - idr_remove(&allocated_dsp, new_dev->idx); - mutex_unlock(&allocated_dsp_lock); - ret = -EINVAL; - } - } - kfree(new_dev); - return ERR_PTR(ret); -} -EXPORT_SYMBOL(display_device_register); - -void display_device_unregister(struct display_device *ddev) -{ - if (!ddev) - return; - // Free device - mutex_lock(&ddev->lock); - device_unregister(ddev->dev); - mutex_unlock(&ddev->lock); - // Mark device index as available - mutex_lock(&allocated_dsp_lock); - idr_remove(&allocated_dsp, ddev->idx); - mutex_unlock(&allocated_dsp_lock); - kfree(ddev); -} -EXPORT_SYMBOL(display_device_unregister); - -static int __init display_class_init(void) -{ - display_class = class_create(THIS_MODULE, "display"); - if (IS_ERR(display_class)) { - printk(KERN_ERR "Failed to create display class\n"); - display_class = NULL; - return -EINVAL; - } - display_class->dev_attrs = display_attrs; - display_class->suspend = display_suspend; - display_class->resume = display_resume; - mutex_init(&allocated_dsp_lock); - return 0; -} - -static void __exit display_class_exit(void) -{ - class_destroy(display_class); -} - -module_init(display_class_init); -module_exit(display_class_exit); - -MODULE_DESCRIPTION("Display Hardware handling"); -MODULE_AUTHOR("James Simmons "); -MODULE_LICENSE("GPL"); - diff --git a/include/linux/display.h b/include/linux/display.h deleted file mode 100644 index 3bf70d6..0000000 --- a/include/linux/display.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (C) 2006 James Simmons - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or (at - * your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - */ - -#ifndef _LINUX_DISPLAY_H -#define _LINUX_DISPLAY_H - -#include - -struct display_device; - -/* This structure defines all the properties of a Display. */ -struct display_driver { - int (*set_contrast)(struct display_device *, unsigned int); - int (*get_contrast)(struct display_device *); - void (*suspend)(struct display_device *, pm_message_t state); - void (*resume)(struct display_device *); - int (*probe)(struct display_device *, void *); - int (*remove)(struct display_device *); - int max_contrast; -}; - -struct display_device { - struct module *owner; /* Owner module */ - struct display_driver *driver; - struct device *parent; /* This is the parent */ - struct device *dev; /* This is this display device */ - struct mutex lock; - void *priv_data; - char type[16]; - char *name; - int idx; -}; - -extern struct display_device *display_device_register(struct display_driver *driver, - struct device *dev, void *devdata); -extern void display_device_unregister(struct display_device *dev); - -extern int probe_edid(struct display_device *dev, void *devdata); - -#define to_display_device(obj) container_of(obj, struct display_device, class_dev) - -#endif -- cgit v0.10.2 From 5d910426a6e80194a50e33351c91abcad266c809 Mon Sep 17 00:00:00 2001 From: Alexander Stein Date: Wed, 5 Oct 2011 09:59:57 +0200 Subject: atmel_lcdfb: Adjust HFP calculation so it matches the manual. In the AT91SAM9263 Manual the HFP part in LCDTIM2 is described as follows: * HFP: Horizontal Front Porch Number of idle LCDDOTCK cycles at the end of the line. Idle period is (HFP+2) LCDDOTCK cycles. It is only a minor issue. I also changed all boards using atmel_lcdfb I found to respect the new calculation. Signed-off-by: Alexander Stein Signed-off-by: Florian Tobias Schandinat diff --git a/arch/arm/mach-at91/board-cap9adk.c b/arch/arm/mach-at91/board-cap9adk.c index 679b0b7..ae962bf 100644 --- a/arch/arm/mach-at91/board-cap9adk.c +++ b/arch/arm/mach-at91/board-cap9adk.c @@ -304,7 +304,7 @@ static struct fb_videomode at91_tft_vga_modes[] = { .xres = 240, .yres = 320, .pixclock = KHZ2PICOS(4965), - .left_margin = 1, .right_margin = 33, + .left_margin = 1, .right_margin = 34, .upper_margin = 1, .lower_margin = 0, .hsync_len = 5, .vsync_len = 1, diff --git a/arch/arm/mach-at91/board-neocore926.c b/arch/arm/mach-at91/board-neocore926.c index 9bc6ab3..583878e 100644 --- a/arch/arm/mach-at91/board-neocore926.c +++ b/arch/arm/mach-at91/board-neocore926.c @@ -235,7 +235,7 @@ static struct fb_videomode at91_tft_vga_modes[] = { .xres = 240, .yres = 320, .pixclock = KHZ2PICOS(5000), - .left_margin = 1, .right_margin = 33, + .left_margin = 1, .right_margin = 34, .upper_margin = 1, .lower_margin = 0, .hsync_len = 5, .vsync_len = 1, diff --git a/arch/arm/mach-at91/board-sam9261ek.c b/arch/arm/mach-at91/board-sam9261ek.c index 5096a0e..8dda83b 100644 --- a/arch/arm/mach-at91/board-sam9261ek.c +++ b/arch/arm/mach-at91/board-sam9261ek.c @@ -370,7 +370,7 @@ static struct fb_videomode at91_stn_modes[] = { .xres = 320, .yres = 240, .pixclock = KHZ2PICOS(1440), - .left_margin = 1, .right_margin = 1, + .left_margin = 1, .right_margin = 2, .upper_margin = 0, .lower_margin = 0, .hsync_len = 1, .vsync_len = 1, @@ -431,7 +431,7 @@ static struct fb_videomode at91_tft_vga_modes[] = { .xres = 240, .yres = 320, .pixclock = KHZ2PICOS(4965), - .left_margin = 1, .right_margin = 33, + .left_margin = 1, .right_margin = 34, .upper_margin = 1, .lower_margin = 0, .hsync_len = 5, .vsync_len = 1, diff --git a/arch/arm/mach-at91/board-sam9263ek.c b/arch/arm/mach-at91/board-sam9263ek.c index ea8f185..e260070 100644 --- a/arch/arm/mach-at91/board-sam9263ek.c +++ b/arch/arm/mach-at91/board-sam9263ek.c @@ -258,7 +258,7 @@ static struct fb_videomode at91_tft_vga_modes[] = { .xres = 240, .yres = 320, .pixclock = KHZ2PICOS(4965), - .left_margin = 1, .right_margin = 33, + .left_margin = 1, .right_margin = 34, .upper_margin = 1, .lower_margin = 0, .hsync_len = 5, .vsync_len = 1, diff --git a/arch/arm/mach-at91/board-sam9m10g45ek.c b/arch/arm/mach-at91/board-sam9m10g45ek.c index ad234cc..5e9a5ca 100644 --- a/arch/arm/mach-at91/board-sam9m10g45ek.c +++ b/arch/arm/mach-at91/board-sam9m10g45ek.c @@ -197,7 +197,7 @@ static struct fb_videomode at91_tft_vga_modes[] = { .xres = 480, .yres = 272, .pixclock = KHZ2PICOS(9000), - .left_margin = 1, .right_margin = 1, + .left_margin = 1, .right_margin = 2, .upper_margin = 40, .lower_margin = 1, .hsync_len = 45, .vsync_len = 1, diff --git a/arch/arm/mach-at91/board-sam9rlek.c b/arch/arm/mach-at91/board-sam9rlek.c index 4f14b54..ad9e5c9 100644 --- a/arch/arm/mach-at91/board-sam9rlek.c +++ b/arch/arm/mach-at91/board-sam9rlek.c @@ -154,7 +154,7 @@ static struct fb_videomode at91_tft_vga_modes[] = { .xres = 240, .yres = 320, .pixclock = KHZ2PICOS(4965), - .left_margin = 1, .right_margin = 33, + .left_margin = 1, .right_margin = 34, .upper_margin = 1, .lower_margin = 0, .hsync_len = 5, .vsync_len = 1, diff --git a/drivers/video/atmel_lcdfb.c b/drivers/video/atmel_lcdfb.c index 244d55b..7e66263 100644 --- a/drivers/video/atmel_lcdfb.c +++ b/drivers/video/atmel_lcdfb.c @@ -396,7 +396,7 @@ static int atmel_lcdfb_check_var(struct fb_var_screeninfo *var, var->lower_margin = min_t(u32, var->lower_margin, ATMEL_LCDC_VFP); var->right_margin = min_t(u32, var->right_margin, - (ATMEL_LCDC_HFP >> ATMEL_LCDC_HFP_OFFSET) + 1); + (ATMEL_LCDC_HFP >> ATMEL_LCDC_HFP_OFFSET) + 2); var->hsync_len = min_t(u32, var->hsync_len, (ATMEL_LCDC_HPW >> ATMEL_LCDC_HPW_OFFSET) + 1); var->left_margin = min_t(u32, var->left_margin, @@ -581,7 +581,7 @@ static int atmel_lcdfb_set_par(struct fb_info *info) lcdc_writel(sinfo, ATMEL_LCDC_TIM1, value); /* Horizontal timing */ - value = (info->var.right_margin - 1) << ATMEL_LCDC_HFP_OFFSET; + value = (info->var.right_margin - 2) << ATMEL_LCDC_HFP_OFFSET; value |= (info->var.hsync_len - 1) << ATMEL_LCDC_HPW_OFFSET; value |= (info->var.left_margin - 1); dev_dbg(info->device, " * LCDTIM2 = %08lx\n", value); -- cgit v0.10.2 From acfdc2e1bdb4b148e7546fe8948d8f75bd2f9377 Mon Sep 17 00:00:00 2001 From: Alexander Stein Date: Wed, 5 Oct 2011 09:59:58 +0200 Subject: atmel_lcdfb: Use proper blanking on negative contrast polarity If used with negative polarity the PWM unit cannot be disabled. This would result in a full contrast screen. Instead let the PWM unit enabled using 0x0 as compare value which darkens the display. In result no power saving is possible if inverted contrast polarity is used. Signed-off-by: Alexander Stein Signed-off-by: Florian Tobias Schandinat diff --git a/drivers/video/atmel_lcdfb.c b/drivers/video/atmel_lcdfb.c index 7e66263..8bfee6a 100644 --- a/drivers/video/atmel_lcdfb.c +++ b/drivers/video/atmel_lcdfb.c @@ -99,8 +99,11 @@ static int atmel_bl_update_status(struct backlight_device *bl) brightness = 0; lcdc_writel(sinfo, ATMEL_LCDC_CONTRAST_VAL, brightness); - lcdc_writel(sinfo, ATMEL_LCDC_CONTRAST_CTR, + if (contrast_ctr & ATMEL_LCDC_POL_POSITIVE) + lcdc_writel(sinfo, ATMEL_LCDC_CONTRAST_CTR, brightness ? contrast_ctr : 0); + else + lcdc_writel(sinfo, ATMEL_LCDC_CONTRAST_CTR, contrast_ctr); bl->props.fb_blank = bl->props.power = sinfo->bl_power = power; -- cgit v0.10.2 From 5d67b89ce88f2db60573de859649b1b5a8c830d6 Mon Sep 17 00:00:00 2001 From: Peter Korsgaard Date: Thu, 13 Oct 2011 16:45:52 +0200 Subject: atmel_lcdfb: support new-style palette format The newer Atmel SoCs use normal 16bit 565 BGR/RGB for the palette data, rather than the special intensity + 555 format. Fill out palette data correctly on these devices, and at the same time respect the RGB/BGR wiring mode. Signed-off-by: Peter Korsgaard Signed-off-by: Florian Tobias Schandinat diff --git a/drivers/video/atmel_lcdfb.c b/drivers/video/atmel_lcdfb.c index 8bfee6a..2226aca 100644 --- a/drivers/video/atmel_lcdfb.c +++ b/drivers/video/atmel_lcdfb.c @@ -684,14 +684,30 @@ static int atmel_lcdfb_setcolreg(unsigned int regno, unsigned int red, case FB_VISUAL_PSEUDOCOLOR: if (regno < 256) { - val = ((red >> 11) & 0x001f); - val |= ((green >> 6) & 0x03e0); - val |= ((blue >> 1) & 0x7c00); - - /* - * TODO: intensity bit. Maybe something like - * ~(red[10] ^ green[10] ^ blue[10]) & 1 - */ + if (cpu_is_at91sam9261() || cpu_is_at91sam9263() + || cpu_is_at91sam9rl()) { + /* old style I+BGR:555 */ + val = ((red >> 11) & 0x001f); + val |= ((green >> 6) & 0x03e0); + val |= ((blue >> 1) & 0x7c00); + + /* + * TODO: intensity bit. Maybe something like + * ~(red[10] ^ green[10] ^ blue[10]) & 1 + */ + } else { + /* new style BGR:565 / RGB:565 */ + if (sinfo->lcd_wiring_mode == + ATMEL_LCDC_WIRING_RGB) { + val = ((blue >> 11) & 0x001f); + val |= ((red >> 0) & 0xf800); + } else { + val = ((red >> 11) & 0x001f); + val |= ((blue >> 0) & 0xf800); + } + + val |= ((green >> 5) & 0x07e0); + } lcdc_writel(sinfo, ATMEL_LCDC_LUT(regno), val); ret = 0; -- cgit v0.10.2 From 38eb6863ed21de9beab792f66cd282c21e0dc10b Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Thu, 20 Oct 2011 13:42:22 +0200 Subject: zorro: Rename Picasso IV Z2 "MEM" to "RAM" for consistency Signed-off-by: Geert Uytterhoeven Signed-off-by: Florian Tobias Schandinat diff --git a/include/linux/zorro_ids.h b/include/linux/zorro_ids.h index 7e74908..74bc53b 100644 --- a/include/linux/zorro_ids.h +++ b/include/linux/zorro_ids.h @@ -360,8 +360,8 @@ #define ZORRO_PROD_VILLAGE_TRONIC_PICASSO_II_II_PLUS_RAM ZORRO_ID(VILLAGE_TRONIC, 0x0B, 0) #define ZORRO_PROD_VILLAGE_TRONIC_PICASSO_II_II_PLUS_REG ZORRO_ID(VILLAGE_TRONIC, 0x0C, 0) #define ZORRO_PROD_VILLAGE_TRONIC_PICASSO_II_II_PLUS_SEGMENTED_MODE ZORRO_ID(VILLAGE_TRONIC, 0x0D, 0) -#define ZORRO_PROD_VILLAGE_TRONIC_PICASSO_IV_Z2_MEM1 ZORRO_ID(VILLAGE_TRONIC, 0x15, 0) -#define ZORRO_PROD_VILLAGE_TRONIC_PICASSO_IV_Z2_MEM2 ZORRO_ID(VILLAGE_TRONIC, 0x16, 0) +#define ZORRO_PROD_VILLAGE_TRONIC_PICASSO_IV_Z2_RAM1 ZORRO_ID(VILLAGE_TRONIC, 0x15, 0) +#define ZORRO_PROD_VILLAGE_TRONIC_PICASSO_IV_Z2_RAM2 ZORRO_ID(VILLAGE_TRONIC, 0x16, 0) #define ZORRO_PROD_VILLAGE_TRONIC_PICASSO_IV_Z2_REG ZORRO_ID(VILLAGE_TRONIC, 0x17, 0) #define ZORRO_PROD_VILLAGE_TRONIC_PICASSO_IV_Z3 ZORRO_ID(VILLAGE_TRONIC, 0x18, 0) #define ZORRO_PROD_VILLAGE_TRONIC_ARIADNE ZORRO_ID(VILLAGE_TRONIC, 0xC9, 0) -- cgit v0.10.2 From 0e0d13364b417a40266999c61671db0ef8690ad3 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Thu, 20 Oct 2011 13:42:23 +0200 Subject: fbdev/cirrusfb: Rewrite Zorro graphics card probing As indicated by commit a7f4d00a82feb5b311f765bf9522bc55bee0684f ("zorro: Defer device_register() until all devices have been identified"), cirrusfb crashes if zorro_find_device() cannot find an expected device. Rewrite the Zorro device probe code to make it more robust, easier to understand, and more extensible. Other logical changes: - For cards that show up as 2 Zorro devices, autoprobe graphics memory sizes based on the size of the Zorro device containing the graphics memory. Acording to the NetBSD sources, this is safe. Signed-off-by: Geert Uytterhoeven Acked-by: Jeff Garzik Signed-off-by: Florian Tobias Schandinat diff --git a/drivers/video/cirrusfb.c b/drivers/video/cirrusfb.c index 6df7c54..357139a 100644 --- a/drivers/video/cirrusfb.c +++ b/drivers/video/cirrusfb.c @@ -280,52 +280,63 @@ MODULE_DEVICE_TABLE(pci, cirrusfb_pci_table); #endif /* CONFIG_PCI */ #ifdef CONFIG_ZORRO -static const struct zorro_device_id cirrusfb_zorro_table[] = { +struct zorrocl { + enum cirrus_board type; /* Board type */ + u32 regoffset; /* Offset of registers in first Zorro device */ + u32 ramsize; /* Size of video RAM in first Zorro device */ + /* If zero, use autoprobe on RAM device */ + u32 ramoffset; /* Offset of video RAM in first Zorro device */ + zorro_id ramid; /* Zorro ID of RAM device */ +}; + +static const struct zorrocl zcl_sd64 __devinitconst = { + .type = BT_SD64, + .ramid = ZORRO_PROD_HELFRICH_SD64_RAM, +}; + +static const struct zorrocl zcl_piccolo __devinitconst = { + .type = BT_PICCOLO, + .ramid = ZORRO_PROD_HELFRICH_PICCOLO_RAM, +}; + +static const struct zorrocl zcl_picasso __devinitconst = { + .type = BT_PICASSO, + .ramid = ZORRO_PROD_VILLAGE_TRONIC_PICASSO_II_II_PLUS_RAM, +}; + +static const struct zorrocl zcl_spectrum __devinitconst = { + .type = BT_SPECTRUM, + .ramid = ZORRO_PROD_GVP_EGS_28_24_SPECTRUM_RAM, +}; + +static const struct zorrocl zcl_picasso4_z3 __devinitconst = { + .type = BT_PICASSO4, + .regoffset = 0x00600000, + .ramsize = 4 * MB_, + .ramoffset = 0x01000000, +}; + + +static const struct zorro_device_id cirrusfb_zorro_table[] __devinitconst = { { - .id = ZORRO_PROD_HELFRICH_SD64_RAM, - .driver_data = BT_SD64, + .id = ZORRO_PROD_HELFRICH_SD64_REG, + .driver_data = (unsigned long)&zcl_sd64, }, { - .id = ZORRO_PROD_HELFRICH_PICCOLO_RAM, - .driver_data = BT_PICCOLO, + .id = ZORRO_PROD_HELFRICH_PICCOLO_REG, + .driver_data = (unsigned long)&zcl_piccolo, }, { - .id = ZORRO_PROD_VILLAGE_TRONIC_PICASSO_II_II_PLUS_RAM, - .driver_data = BT_PICASSO, + .id = ZORRO_PROD_VILLAGE_TRONIC_PICASSO_II_II_PLUS_REG, + .driver_data = (unsigned long)&zcl_picasso, }, { - .id = ZORRO_PROD_GVP_EGS_28_24_SPECTRUM_RAM, - .driver_data = BT_SPECTRUM, + .id = ZORRO_PROD_GVP_EGS_28_24_SPECTRUM_REG, + .driver_data = (unsigned long)&zcl_spectrum, }, { .id = ZORRO_PROD_VILLAGE_TRONIC_PICASSO_IV_Z3, - .driver_data = BT_PICASSO4, + .driver_data = (unsigned long)&zcl_picasso4_z3, }, { 0 } }; MODULE_DEVICE_TABLE(zorro, cirrusfb_zorro_table); - -static const struct { - zorro_id id2; - unsigned long size; -} cirrusfb_zorro_table2[] = { - [BT_SD64] = { - .id2 = ZORRO_PROD_HELFRICH_SD64_REG, - .size = 0x400000 - }, - [BT_PICCOLO] = { - .id2 = ZORRO_PROD_HELFRICH_PICCOLO_REG, - .size = 0x200000 - }, - [BT_PICASSO] = { - .id2 = ZORRO_PROD_VILLAGE_TRONIC_PICASSO_II_II_PLUS_REG, - .size = 0x200000 - }, - [BT_SPECTRUM] = { - .id2 = ZORRO_PROD_GVP_EGS_28_24_SPECTRUM_REG, - .size = 0x200000 - }, - [BT_PICASSO4] = { - .id2 = 0, - .size = 0x400000 - } -}; #endif /* CONFIG_ZORRO */ #ifdef CIRRUSFB_DEBUG @@ -1956,16 +1967,12 @@ static void cirrusfb_zorro_unmap(struct fb_info *info) struct cirrusfb_info *cinfo = info->par; struct zorro_dev *zdev = to_zorro_dev(info->device); - zorro_release_device(zdev); - - if (cinfo->btype == BT_PICASSO4) { - cinfo->regbase -= 0x600000; - iounmap((void *)cinfo->regbase); + if (info->fix.smem_start > 16 * MB_) iounmap(info->screen_base); - } else { - if (zorro_resource_start(zdev) > 0x01000000) - iounmap(info->screen_base); - } + if (info->fix.mmio_start > 16 * MB_) + iounmap(cinfo->regbase); + + zorro_release_device(zdev); } #endif /* CONFIG_ZORRO */ @@ -2222,115 +2229,102 @@ static struct pci_driver cirrusfb_pci_driver = { static int __devinit cirrusfb_zorro_register(struct zorro_dev *z, const struct zorro_device_id *ent) { - struct cirrusfb_info *cinfo; struct fb_info *info; + int error; + const struct zorrocl *zcl; enum cirrus_board btype; - struct zorro_dev *z2 = NULL; - unsigned long board_addr, board_size, size; - int ret; - - btype = ent->driver_data; - if (cirrusfb_zorro_table2[btype].id2) - z2 = zorro_find_device(cirrusfb_zorro_table2[btype].id2, NULL); - size = cirrusfb_zorro_table2[btype].size; + unsigned long regbase, ramsize, rambase; + struct cirrusfb_info *cinfo; info = framebuffer_alloc(sizeof(struct cirrusfb_info), &z->dev); if (!info) { printk(KERN_ERR "cirrusfb: could not allocate memory\n"); - ret = -ENOMEM; - goto err_out; + return -ENOMEM; } - dev_info(info->device, "%s board detected\n", - cirrusfb_board_info[btype].name); - - cinfo = info->par; - cinfo->btype = btype; - - assert(z); - assert(btype != BT_NONE); + zcl = (const struct zorrocl *)ent->driver_data; + btype = zcl->type; + regbase = zorro_resource_start(z) + zcl->regoffset; + ramsize = zcl->ramsize; + if (ramsize) { + rambase = zorro_resource_start(z) + zcl->ramoffset; + } else { + struct zorro_dev *ram = zorro_find_device(zcl->ramid, NULL); + if (!ram || !zorro_resource_len(ram)) { + dev_err(info->device, "No video RAM found\n"); + error = -ENODEV; + goto err_release_fb; + } + rambase = zorro_resource_start(ram); + ramsize = zorro_resource_len(ram); + } - board_addr = zorro_resource_start(z); - board_size = zorro_resource_len(z); - info->screen_size = size; + dev_info(info->device, + "%s board detected, REG at 0x%lx, %lu MiB RAM at 0x%lx\n", + cirrusfb_board_info[btype].name, regbase, ramsize / MB_, + rambase); if (!zorro_request_device(z, "cirrusfb")) { - dev_err(info->device, "cannot reserve region 0x%lx, abort\n", - board_addr); - ret = -EBUSY; + dev_err(info->device, "Cannot reserve %pR\n", &z->resource); + error = -EBUSY; goto err_release_fb; } - ret = -EIO; - - if (btype == BT_PICASSO4) { - dev_info(info->device, " REG at $%lx\n", board_addr + 0x600000); - - /* To be precise, for the P4 this is not the */ - /* begin of the board, but the begin of RAM. */ - /* for P4, map in its address space in 2 chunks (### TEST! ) */ - /* (note the ugly hardcoded 16M number) */ - cinfo->regbase = ioremap(board_addr, 16777216); - if (!cinfo->regbase) - goto err_release_region; - - dev_dbg(info->device, "Virtual address for board set to: $%p\n", - cinfo->regbase); - cinfo->regbase += 0x600000; - info->fix.mmio_start = board_addr + 0x600000; - - info->fix.smem_start = board_addr + 16777216; - info->screen_base = ioremap(info->fix.smem_start, 16777216); - if (!info->screen_base) - goto err_unmap_regbase; - } else { - dev_info(info->device, " REG at $%lx\n", - (unsigned long) z2->resource.start); - - info->fix.smem_start = board_addr; - if (board_addr > 0x01000000) - info->screen_base = ioremap(board_addr, board_size); - else - info->screen_base = (caddr_t) ZTWO_VADDR(board_addr); - if (!info->screen_base) - goto err_release_region; + cinfo = info->par; + cinfo->btype = btype; - /* set address for REG area of board */ - cinfo->regbase = (caddr_t) ZTWO_VADDR(z2->resource.start); - info->fix.mmio_start = z2->resource.start; + info->fix.mmio_start = regbase; + cinfo->regbase = regbase > 16 * MB_ ? ioremap(regbase, 64 * 1024) + : (caddr_t)ZTWO_VADDR(regbase); + if (!cinfo->regbase) { + dev_err(info->device, "Cannot map registers\n"); + error = -EIO; + goto err_release_dev; + } - dev_dbg(info->device, "Virtual address for board set to: $%p\n", - cinfo->regbase); + info->fix.smem_start = rambase; + info->screen_size = ramsize; + info->screen_base = rambase > 16 * MB_ ? ioremap(rambase, ramsize) + : (caddr_t)ZTWO_VADDR(rambase); + if (!info->screen_base) { + dev_err(info->device, "Cannot map video RAM\n"); + error = -EIO; + goto err_unmap_reg; } + cinfo->unmap = cirrusfb_zorro_unmap; dev_info(info->device, - "Cirrus Logic chipset on Zorro bus, RAM (%lu MB) at $%lx\n", - board_size / MB_, board_addr); - - zorro_set_drvdata(z, info); + "Cirrus Logic chipset on Zorro bus, RAM (%lu MiB) at 0x%lx\n", + ramsize / MB_, rambase); /* MCLK select etc. */ if (cirrusfb_board_info[btype].init_sr1f) vga_wseq(cinfo->regbase, CL_SEQR1F, cirrusfb_board_info[btype].sr1f); - ret = cirrusfb_register(info); - if (!ret) - return 0; + error = cirrusfb_register(info); + if (error) { + dev_err(info->device, "Failed to register device, error %d\n", + error); + goto err_unmap_ram; + } - if (btype == BT_PICASSO4 || board_addr > 0x01000000) + zorro_set_drvdata(z, info); + return 0; + +err_unmap_ram: + if (rambase > 16 * MB_) iounmap(info->screen_base); -err_unmap_regbase: - if (btype == BT_PICASSO4) - iounmap(cinfo->regbase - 0x600000); -err_release_region: - release_region(board_addr, board_size); +err_unmap_reg: + if (regbase > 16 * MB_) + iounmap(cinfo->regbase); +err_release_dev: + zorro_release_device(z); err_release_fb: framebuffer_release(info); -err_out: - return ret; + return error; } void __devexit cirrusfb_zorro_unregister(struct zorro_dev *z) @@ -2338,6 +2332,7 @@ void __devexit cirrusfb_zorro_unregister(struct zorro_dev *z) struct fb_info *info = zorro_get_drvdata(z); cirrusfb_cleanup(info); + zorro_set_drvdata(z, NULL); } static struct zorro_driver cirrusfb_zorro_driver = { -- cgit v0.10.2 From 17bdf48952d3f5c0be8137058f81d398d4606820 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Thu, 20 Oct 2011 13:42:24 +0200 Subject: fbdev/cirrusfb: Add support for Picasso IV in Zorro II mode In Zorro II mode, the Village Tronic Picasso IV graphics card shows up as either 2 or 3 Zorro devices: - One for the registers of the Cirrus Logic graphics chip, - One for the first bank of 2 MiB of graphics memory, - An optional one for the second bank of 2 MiB of graphics memory, if there was enough free Zorro II address space. Based on src/sys/arch/amiga/dev/grf_cl.c from NetBSD. Signed-off-by: Geert Uytterhoeven Acked-by: Jeff Garzik Signed-off-by: Florian Tobias Schandinat diff --git a/drivers/video/cirrusfb.c b/drivers/video/cirrusfb.c index 357139a..816433f 100644 --- a/drivers/video/cirrusfb.c +++ b/drivers/video/cirrusfb.c @@ -287,6 +287,7 @@ struct zorrocl { /* If zero, use autoprobe on RAM device */ u32 ramoffset; /* Offset of video RAM in first Zorro device */ zorro_id ramid; /* Zorro ID of RAM device */ + zorro_id ramid2; /* Zorro ID of optional second RAM device */ }; static const struct zorrocl zcl_sd64 __devinitconst = { @@ -316,6 +317,13 @@ static const struct zorrocl zcl_picasso4_z3 __devinitconst = { .ramoffset = 0x01000000, }; +static const struct zorrocl zcl_picasso4_z2 __devinitconst = { + .type = BT_PICASSO4, + .regoffset = 0x10000, + .ramid = ZORRO_PROD_VILLAGE_TRONIC_PICASSO_IV_Z2_RAM1, + .ramid2 = ZORRO_PROD_VILLAGE_TRONIC_PICASSO_IV_Z2_RAM2, +}; + static const struct zorro_device_id cirrusfb_zorro_table[] __devinitconst = { { @@ -333,6 +341,9 @@ static const struct zorro_device_id cirrusfb_zorro_table[] __devinitconst = { }, { .id = ZORRO_PROD_VILLAGE_TRONIC_PICASSO_IV_Z3, .driver_data = (unsigned long)&zcl_picasso4_z3, + }, { + .id = ZORRO_PROD_VILLAGE_TRONIC_PICASSO_IV_Z2_REG, + .driver_data = (unsigned long)&zcl_picasso4_z2, }, { 0 } }; @@ -2257,6 +2268,16 @@ static int __devinit cirrusfb_zorro_register(struct zorro_dev *z, } rambase = zorro_resource_start(ram); ramsize = zorro_resource_len(ram); + if (zcl->ramid2 && + (ram = zorro_find_device(zcl->ramid2, NULL))) { + if (zorro_resource_start(ram) != rambase + ramsize) { + dev_warn(info->device, + "Skipping non-contiguous RAM at %pR\n", + &ram->resource); + } else { + ramsize += zorro_resource_len(ram); + } + } } dev_info(info->device, -- cgit v0.10.2 From e78bb882bf318bb41e17b33729cca3bdd26b42a0 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Thu, 20 Oct 2011 13:42:25 +0200 Subject: fbdev/cirrusfb: Add support for "64 MiB" version of Picasso IV Some Village Tronic Picasso IV graphics cards identify as a 64 MiB Zorro device in Zorro III mode. While the total graphics memory size is the same on such cards, the offset of the graphics memory differs. Add a quirk to handle this. Based on src/sys/arch/amiga/dev/grf_cl.c from NetBSD. Signed-off-by: Geert Uytterhoeven Acked-by: Jeff Garzik Signed-off-by: Florian Tobias Schandinat diff --git a/drivers/video/cirrusfb.c b/drivers/video/cirrusfb.c index 816433f..6ea505c 100644 --- a/drivers/video/cirrusfb.c +++ b/drivers/video/cirrusfb.c @@ -314,7 +314,7 @@ static const struct zorrocl zcl_picasso4_z3 __devinitconst = { .type = BT_PICASSO4, .regoffset = 0x00600000, .ramsize = 4 * MB_, - .ramoffset = 0x01000000, + .ramoffset = 0x01000000, /* 0x02000000 for 64 MiB boards */ }; static const struct zorrocl zcl_picasso4_z2 __devinitconst = { @@ -2259,6 +2259,10 @@ static int __devinit cirrusfb_zorro_register(struct zorro_dev *z, ramsize = zcl->ramsize; if (ramsize) { rambase = zorro_resource_start(z) + zcl->ramoffset; + if (zorro_resource_len(z) == 64 * MB_) { + /* Quirk for 64 MiB Picasso IV */ + rambase += zcl->ramoffset; + } } else { struct zorro_dev *ram = zorro_find_device(zcl->ramid, NULL); if (!ram || !zorro_resource_len(ram)) { -- cgit v0.10.2 From 4420dd2b306f1997232a13462bca0d420be5b1b8 Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Mon, 7 Nov 2011 15:03:01 +0900 Subject: video: s3c-fb: fix transparency length for pixel blending Transparency length is fixed for pixel blending in order to support ARGB 8888 format. Signed-off-by: Jingoo Han Signed-off-by: Florian Tobias Schandinat diff --git a/drivers/video/s3c-fb.c b/drivers/video/s3c-fb.c index 0753b1c..12eaee0 100644 --- a/drivers/video/s3c-fb.c +++ b/drivers/video/s3c-fb.c @@ -621,7 +621,8 @@ static int s3c_fb_set_par(struct fb_info *info) } else if (var->transp.length == 1) data |= WINCON1_BPPMODE_25BPP_A1888 | WINCON1_BLD_PIX; - else if (var->transp.length == 4) + else if ((var->transp.length == 4) || + (var->transp.length == 8)) data |= WINCON1_BPPMODE_28BPP_A4888 | WINCON1_BLD_PIX | WINCON1_ALPHA_SEL; else -- cgit v0.10.2 From 2440f7aff46af4187d0518e92adaddf475aa82b0 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 11 Nov 2011 20:26:03 -0200 Subject: [media] Properly implement ITU-T J.88 Annex C support The Annex C support were broken with the previous implementation, as, at xc5000 and tda18271c2dd, it were choosing the wrong bandwidth for some symbol rates. At DRX-J, it were always selecting Annex A, even having Annex C support coded there. Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/common/tuners/xc5000.c b/drivers/media/common/tuners/xc5000.c index aa1b2e8..88b329c 100644 --- a/drivers/media/common/tuners/xc5000.c +++ b/drivers/media/common/tuners/xc5000.c @@ -628,20 +628,12 @@ static void xc_debug_dump(struct xc5000_priv *priv) dprintk(1, "*** Quality (0:<8dB, 7:>56dB) = %d\n", quality); } -/* - * As defined on EN 300 429, the DVB-C roll-off factor is 0.15. - * So, the amount of the needed bandwith is given by: - * Bw = Symbol_rate * (1 + 0.15) - * As such, the maximum symbol rate supported by 6 MHz is given by: - * max_symbol_rate = 6 MHz / 1.15 = 5217391 Bauds - */ -#define MAX_SYMBOL_RATE_6MHz 5217391 - static int xc5000_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) { struct xc5000_priv *priv = fe->tuner_priv; int ret; + u32 bw; if (xc5000_is_firmware_loaded(fe) != XC_RESULT_SUCCESS) { if (xc_load_fw_and_init_tuner(fe) != XC_RESULT_SUCCESS) { @@ -707,11 +699,19 @@ static int xc5000_set_params(struct dvb_frontend *fe, dprintk(1, "%s() QAM modulation\n", __func__); priv->rf_mode = XC_RF_MODE_CABLE; /* - * Using a 8MHz bandwidth sometimes fail - * with 6MHz-spaced channels, due to inter-carrier - * interference. So, use DTV6 firmware + * Using a higher bandwidth at the tuner filter may + * allow inter-carrier interference. + * So, determine the minimal channel spacing, in order + * to better adjust the tuner filter. + * According with ITU-T J.83, the bandwidth is given by: + * bw = Simbol Rate * (1 + roll_off), where the roll_off + * is equal to 0.15 for Annex A, and 0.13 for annex C */ - if (params->u.qam.symbol_rate <= MAX_SYMBOL_RATE_6MHz) { + if (fe->dtv_property_cache.rolloff == ROLLOFF_13) + bw = (params->u.qam.symbol_rate * 13) / 10; + else + bw = (params->u.qam.symbol_rate * 15) / 10; + if (bw <= 6000000) { priv->bandwidth = BANDWIDTH_6_MHZ; priv->video_standard = DTV6; priv->freq_hz = params->frequency - 1750000; diff --git a/drivers/media/dvb/frontends/drxk_hard.c b/drivers/media/dvb/frontends/drxk_hard.c index f6431ef..dc13fd8 100644 --- a/drivers/media/dvb/frontends/drxk_hard.c +++ b/drivers/media/dvb/frontends/drxk_hard.c @@ -6218,6 +6218,13 @@ static int drxk_set_parameters(struct dvb_frontend *fe, return -EINVAL; } + if (state->m_OperationMode == OM_QAM_ITU_A || + state->m_OperationMode == OM_QAM_ITU_C) { + if (fe->dtv_property_cache.rolloff == ROLLOFF_13) + state->m_OperationMode = OM_QAM_ITU_C; + else + state->m_OperationMode = OM_QAM_ITU_A; + } if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 1); diff --git a/drivers/media/dvb/frontends/tda18271c2dd.c b/drivers/media/dvb/frontends/tda18271c2dd.c index 1b1bf20..de544f6 100644 --- a/drivers/media/dvb/frontends/tda18271c2dd.c +++ b/drivers/media/dvb/frontends/tda18271c2dd.c @@ -1123,20 +1123,6 @@ static int release(struct dvb_frontend *fe) return 0; } -/* - * As defined on EN 300 429 Annex A and on ITU-T J.83 annex A, the DVB-C - * roll-off factor is 0.15. - * According with the specs, the amount of the needed bandwith is given by: - * Bw = Symbol_rate * (1 + 0.15) - * As such, the maximum symbol rate supported by 6 MHz is - * max_symbol_rate = 6 MHz / 1.15 = 5217391 Bauds - *NOTE: For ITU-T J.83 Annex C, the roll-off factor is 0.13. So: - * max_symbol_rate = 6 MHz / 1.13 = 5309735 Baud - * That means that an adjustment is needed for Japan, - * but, as currently DRX-K is hardcoded to Annex A, let's stick - * with 0.15 roll-off factor. - */ -#define MAX_SYMBOL_RATE_6MHz 5217391 static int set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) @@ -1144,6 +1130,7 @@ static int set_params(struct dvb_frontend *fe, struct tda_state *state = fe->tuner_priv; int status = 0; int Standard; + u32 bw; state->m_Frequency = params->frequency; @@ -1161,8 +1148,23 @@ static int set_params(struct dvb_frontend *fe, break; } else if (fe->ops.info.type == FE_QAM) { - if (params->u.qam.symbol_rate <= MAX_SYMBOL_RATE_6MHz) + /* + * Using a higher bandwidth at the tuner filter may + * allow inter-carrier interference. + * So, determine the minimal channel spacing, in order + * to better adjust the tuner filter. + * According with ITU-T J.83, the bandwidth is given by: + * bw = Simbol Rate * (1 + roll_off), where the roll_off + * is equal to 0.15 for Annex A, and 0.13 for annex C + */ + if (fe->dtv_property_cache.rolloff == ROLLOFF_13) + bw = (params->u.qam.symbol_rate * 13) / 10; + else + bw = (params->u.qam.symbol_rate * 15) / 10; + if (bw <= 6000000) Standard = HF_DVBC_6MHZ; + else if (bw <= 7000000) + Standard = HF_DVBC_7MHZ; else Standard = HF_DVBC_8MHZ; } else -- cgit v0.10.2 From 358142dd8cbbfa2abb1090aca1b636b98ed75ef5 Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Thu, 3 Nov 2011 10:09:57 -0700 Subject: scripts/tags.sh: Add Page flag function magic It takes a while to find the macro-magically defined Page*() functions defined in include/linux/page-flags.h if you're new to the kernel. Add some magic to the tags script to transform these macros into the actual functions they are, so that tag jumping in the mm code is a bit easier. Signed-off-by: Stephen Boyd Signed-off-by: Michal Marek diff --git a/scripts/tags.sh b/scripts/tags.sh index 38f6617..028dc5c 100755 --- a/scripts/tags.sh +++ b/scripts/tags.sh @@ -132,7 +132,28 @@ exuberant() --regex-asm='/^(ENTRY|_GLOBAL)\(([^)]*)\).*/\2/' \ --regex-c='/^SYSCALL_DEFINE[[:digit:]]?\(([^,)]*).*/sys_\1/' \ --regex-c++='/^TRACE_EVENT\(([^,)]*).*/trace_\1/' \ - --regex-c++='/^DEFINE_EVENT\([^,)]*, *([^,)]*).*/trace_\1/' + --regex-c++='/^DEFINE_EVENT\([^,)]*, *([^,)]*).*/trace_\1/' \ + --regex-c++='/PAGEFLAG\(([^,)]*).*/Page\1/' \ + --regex-c++='/PAGEFLAG\(([^,)]*).*/SetPage\1/' \ + --regex-c++='/PAGEFLAG\(([^,)]*).*/ClearPage\1/' \ + --regex-c++='/TESTSETFLAG\(([^,)]*).*/TestSetPage\1/' \ + --regex-c++='/TESTPAGEFLAG\(([^,)]*).*/Page\1/' \ + --regex-c++='/SETPAGEFLAG\(([^,)]*).*/SetPage\1/' \ + --regex-c++='/__SETPAGEFLAG\(([^,)]*).*/__SetPage\1/' \ + --regex-c++='/TESTCLEARFLAG\(([^,)]*).*/TestClearPage\1/' \ + --regex-c++='/__TESTCLEARFLAG\(([^,)]*).*/TestClearPage\1/' \ + --regex-c++='/CLEARPAGEFLAG\(([^,)]*).*/ClearPage\1/' \ + --regex-c++='/__CLEARPAGEFLAG\(([^,)]*).*/__ClearPage\1/' \ + --regex-c++='/__PAGEFLAG\(([^,)]*).*/__SetPage\1/' \ + --regex-c++='/__PAGEFLAG\(([^,)]*).*/__ClearPage\1/' \ + --regex-c++='/PAGEFLAG_FALSE\(([^,)]*).*/Page\1/' \ + --regex-c++='/TESTSCFLAG\(([^,)]*).*/TestSetPage\1/' \ + --regex-c++='/TESTSCFLAG\(([^,)]*).*/TestClearPage\1/' \ + --regex-c++='/SETPAGEFLAG_NOOP\(([^,)]*).*/SetPage\1/' \ + --regex-c++='/CLEARPAGEFLAG_NOOP\(([^,)]*).*/ClearPage\1/' \ + --regex-c++='/__CLEARPAGEFLAG_NOOP\(([^,)]*).*/__ClearPage\1/' \ + --regex-c++='/TESTCLEARFLAG_FALSE\(([^,)]*).*/TestClearPage\1/' \ + --regex-c++='/__TESTCLEARFLAG_FALSE\(([^,)]*).*/__TestClearPage\1/' all_kconfigs | xargs $1 -a \ --langdef=kconfig --language-force=kconfig \ @@ -154,7 +175,28 @@ emacs() --regex='/^(ENTRY|_GLOBAL)(\([^)]*\)).*/\2/' \ --regex='/^SYSCALL_DEFINE[0-9]?(\([^,)]*\).*/sys_\1/' \ --regex='/^TRACE_EVENT(\([^,)]*\).*/trace_\1/' \ - --regex='/^DEFINE_EVENT([^,)]*, *\([^,)]*\).*/trace_\1/' + --regex='/^DEFINE_EVENT([^,)]*, *\([^,)]*\).*/trace_\1/' \ + --regex='/PAGEFLAG\(([^,)]*).*/Page\1/' \ + --regex='/PAGEFLAG\(([^,)]*).*/SetPage\1/' \ + --regex='/PAGEFLAG\(([^,)]*).*/ClearPage\1/' \ + --regex='/TESTSETFLAG\(([^,)]*).*/TestSetPage\1/' \ + --regex='/TESTPAGEFLAG\(([^,)]*).*/Page\1/' \ + --regex='/SETPAGEFLAG\(([^,)]*).*/SetPage\1/' \ + --regex='/__SETPAGEFLAG\(([^,)]*).*/__SetPage\1/' \ + --regex='/TESTCLEARFLAG\(([^,)]*).*/TestClearPage\1/' \ + --regex='/__TESTCLEARFLAG\(([^,)]*).*/TestClearPage\1/' \ + --regex='/CLEARPAGEFLAG\(([^,)]*).*/ClearPage\1/' \ + --regex='/__CLEARPAGEFLAG\(([^,)]*).*/__ClearPage\1/' \ + --regex='/__PAGEFLAG\(([^,)]*).*/__SetPage\1/' \ + --regex='/__PAGEFLAG\(([^,)]*).*/__ClearPage\1/' \ + --regex='/PAGEFLAG_FALSE\(([^,)]*).*/Page\1/' \ + --regex='/TESTSCFLAG\(([^,)]*).*/TestSetPage\1/' \ + --regex='/TESTSCFLAG\(([^,)]*).*/TestClearPage\1/' \ + --regex='/SETPAGEFLAG_NOOP\(([^,)]*).*/SetPage\1/' \ + --regex='/CLEARPAGEFLAG_NOOP\(([^,)]*).*/ClearPage\1/' \ + --regex='/__CLEARPAGEFLAG_NOOP\(([^,)]*).*/__ClearPage\1/' \ + --regex='/TESTCLEARFLAG_FALSE\(([^,)]*).*/TestClearPage\1/' \ + --regex='/__TESTCLEARFLAG_FALSE\(([^,)]*).*/__TestClearPage\1/' all_kconfigs | xargs $1 -a \ --regex='/^[ \t]*\(\(menu\)*config\)[ \t]+\([a-zA-Z0-9_]+\)/\3/' -- cgit v0.10.2 From 353de31b86850309b205a3d4cc1294052471b14d Mon Sep 17 00:00:00 2001 From: "J. Bruce Fields" Date: Tue, 15 Nov 2011 19:25:03 -0500 Subject: nfsd4: fix CONFIG_NFSD_FAULT_INJECTION compile error Reported-by: Stephen Rothwell Signed-off-by: J. Bruce Fields diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index dcbe7f3..7e4edbd 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -4442,7 +4442,7 @@ static void release_openowner_sop(struct nfs4_stateowner *sop) release_openowner(openowner(sop)); } -static int nfsd_release_n_owners(u64 num, bool is_open_owner +static int nfsd_release_n_owners(u64 num, bool is_open_owner, void (*release_sop)(struct nfs4_stateowner *)) { int i, count = 0; -- cgit v0.10.2 From 009673b439cf74d70a486fca0177e274febd81a7 Mon Sep 17 00:00:00 2001 From: "J. Bruce Fields" Date: Mon, 7 Nov 2011 17:40:10 -0500 Subject: nfsd4: add a separate (lockowner, inode) lookup Address the possible performance regression mentioned in "nfsd4: hash lockowners to simplify RELEASE_LOCKOWNER" by providing a separate (lockowner, inode) hash. Really, I doubt this matters much, but I think it's likely we'll change these data structures here and I'd rather that the need for (owner, inode) lookups be well-documented. Signed-off-by: J. Bruce Fields diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 7e4edbd..a84978c 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -514,6 +514,7 @@ static void unhash_lockowner(struct nfs4_lockowner *lo) list_del(&lo->lo_owner.so_strhash); list_del(&lo->lo_perstateid); + list_del(&lo->lo_owner_ino_hash); while (!list_empty(&lo->lo_owner.so_stateids)) { stp = list_first_entry(&lo->lo_owner.so_stateids, struct nfs4_ol_stateid, st_perstateowner); @@ -3722,6 +3723,10 @@ out: #define LOFF_OVERFLOW(start, len) ((u64)(len) > ~(u64)(start)) +#define LOCKOWNER_INO_HASH_BITS 8 +#define LOCKOWNER_INO_HASH_SIZE (1 << LOCKOWNER_INO_HASH_BITS) +#define LOCKOWNER_INO_HASH_MASK (LOCKOWNER_INO_HASH_SIZE - 1) + static inline u64 end_offset(u64 start, u64 len) { @@ -3742,6 +3747,15 @@ last_byte_offset(u64 start, u64 len) return end > start ? end - 1: NFS4_MAX_UINT64; } +static unsigned int lockowner_ino_hashval(struct inode *inode, u32 cl_id, struct xdr_netobj *ownername) +{ + return (file_hashval(inode) + cl_id + + opaque_hashval(ownername->data, ownername->len)) + & LOCKOWNER_INO_HASH_MASK; +} + +static struct list_head lockowner_ino_hashtbl[LOCKOWNER_INO_HASH_SIZE]; + /* * TODO: Linux file offsets are _signed_ 64-bit quantities, which means that * we can't properly handle lock requests that go beyond the (2^63 - 1)-th @@ -3809,14 +3823,10 @@ static struct nfs4_lockowner * find_lockowner_str(struct inode *inode, clientid_t *clid, struct xdr_netobj *owner) { - unsigned int hashval = ownerstr_hashval(clid->cl_id, owner); + unsigned int hashval = lockowner_ino_hashval(inode, clid->cl_id, owner); struct nfs4_lockowner *lo; - struct nfs4_stateowner *op; - list_for_each_entry(op, &ownerstr_hashtbl[hashval], so_strhash) { - if (op->so_is_open_owner) - continue; - lo = lockowner(op); + list_for_each_entry(lo, &lockowner_ino_hashtbl[hashval], lo_owner_ino_hash) { if (same_lockowner_ino(lo, inode, clid, owner)) return lo; } @@ -3825,7 +3835,12 @@ find_lockowner_str(struct inode *inode, clientid_t *clid, static void hash_lockowner(struct nfs4_lockowner *lo, unsigned int strhashval, struct nfs4_client *clp, struct nfs4_ol_stateid *open_stp) { + struct inode *inode = open_stp->st_file->fi_inode; + unsigned int inohash = lockowner_ino_hashval(inode, + clp->cl_clientid.cl_id, &lo->lo_owner.so_owner); + list_add(&lo->lo_owner.so_strhash, &ownerstr_hashtbl[strhashval]); + list_add(&lo->lo_owner_ino_hash, &lockowner_ino_hashtbl[inohash]); list_add(&lo->lo_perstateid, &open_stp->st_lockowners); } @@ -4548,6 +4563,8 @@ nfs4_state_init(void) for (i = 0; i < OWNER_HASH_SIZE; i++) { INIT_LIST_HEAD(&ownerstr_hashtbl[i]); } + for (i = 0; i < LOCKOWNER_INO_HASH_SIZE; i++) + INIT_LIST_HEAD(&lockowner_ino_hashtbl[i]); memset(&onestateid, ~0, sizeof(stateid_t)); INIT_LIST_HEAD(&close_lru); INIT_LIST_HEAD(&client_lru); diff --git a/fs/nfsd/state.h b/fs/nfsd/state.h index a3cf384..89c2cd8 100644 --- a/fs/nfsd/state.h +++ b/fs/nfsd/state.h @@ -366,6 +366,7 @@ struct nfs4_openowner { struct nfs4_lockowner { struct nfs4_stateowner lo_owner; /* must be first element */ + struct list_head lo_owner_ino_hash; /* hash by owner,file */ struct list_head lo_perstateid; /* for lockowners only */ struct list_head lo_list; /* for temporary uses */ }; -- cgit v0.10.2 From 4e145349a1fe16ba8689553f0ffa5b223fba5327 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 16 Nov 2011 14:38:28 -0200 Subject: [media] em28xx: Fix some Terratec entries (H5 and XS) As reported by Andreas Oberritter , changeset 33ba28eebc3e1758e6adc1fcec9e1e3151bac453 did the wrong thing. Fix it to properly reflect the entries for Terratec H5 revs 1 and 2, and restore Terratec XS entry. Signed-off-by: Mauro Carvalho Chehab diff --git a/Documentation/video4linux/CARDLIST.em28xx b/Documentation/video4linux/CARDLIST.em28xx index d8c8544..7734b2c 100644 --- a/Documentation/video4linux/CARDLIST.em28xx +++ b/Documentation/video4linux/CARDLIST.em28xx @@ -11,7 +11,7 @@ 10 -> Hauppauge WinTV HVR 900 (em2880) [2040:6500] 11 -> Terratec Hybrid XS (em2880) 12 -> Kworld PVR TV 2800 RF (em2820/em2840) - 13 -> Terratec Prodigy XS (em2880) [0ccd:10ad] + 13 -> Terratec Prodigy XS (em2880) 14 -> SIIG AVTuner-PVR / Pixelview Prolink PlayTV USB 2.0 (em2820/em2840) 15 -> V-Gear PocketTV (em2800) 16 -> Hauppauge WinTV HVR 950 (em2883) [2040:6513,2040:6517,2040:651b] @@ -41,7 +41,7 @@ 40 -> Plextor ConvertX PX-TV100U (em2861) [093b:a005] 41 -> Kworld 350 U DVB-T (em2870) [eb1a:e350] 42 -> Kworld 355 U DVB-T (em2870) [eb1a:e355,eb1a:e357] - 43 -> Terratec Cinergy T XS (em2870) + 43 -> Terratec Cinergy T XS (em2870) [0ccd:0043] 44 -> Terratec Cinergy T XS (MT2060) (em2870) 45 -> Pinnacle PCTV DVB-T (em2870) 46 -> Compro, VideoMate U3 (em2870) [185b:2870] @@ -76,5 +76,5 @@ 76 -> KWorld PlusTV 340U or UB435-Q (ATSC) (em2870) [1b80:a340] 77 -> EM2874 Leadership ISDBT (em2874) 78 -> PCTV nanoStick T2 290e (em28174) - 79 -> Terratec Cinergy H5 (em2884) [0ccd:0043,0ccd:10a2] + 79 -> Terratec Cinergy H5 (em2884) [0ccd:10a2,0ccd:10ad] 80 -> PCTV DVB-S2 Stick (460e) (em28174) diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c index 9b747c2..19a5be3 100644 --- a/drivers/media/video/em28xx/em28xx-cards.c +++ b/drivers/media/video/em28xx/em28xx-cards.c @@ -1914,11 +1914,11 @@ struct usb_device_id em28xx_id_table[] = { { USB_DEVICE(0x0ccd, 0x0042), .driver_info = EM2882_BOARD_TERRATEC_HYBRID_XS }, { USB_DEVICE(0x0ccd, 0x0043), + .driver_info = EM2870_BOARD_TERRATEC_XS }, + { USB_DEVICE(0x0ccd, 0x10a2), /* H5 Rev. 1 */ .driver_info = EM2884_BOARD_TERRATEC_H5 }, - { USB_DEVICE(0x0ccd, 0x10a2), /* Rev. 1 */ + { USB_DEVICE(0x0ccd, 0x10ad), /* H5 Rev. 2 */ .driver_info = EM2884_BOARD_TERRATEC_H5 }, - { USB_DEVICE(0x0ccd, 0x10ad), /* Rev. 2 */ - .driver_info = EM2880_BOARD_TERRATEC_PRODIGY_XS }, { USB_DEVICE(0x0ccd, 0x0084), .driver_info = EM2860_BOARD_TERRATEC_AV350 }, { USB_DEVICE(0x0ccd, 0x0096), -- cgit v0.10.2 From cb97914b04e7b587cf555ec5b1c69d61014f3378 Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Fri, 11 Nov 2011 15:20:34 -0800 Subject: kbuild: Add support for installing generated asm headers Generated asm headers are supposed to live in arch/*/include/generated/asm, but objhdr-y expect them to live in the same directory they are generated in. Instead of trying to cut that particular Gordian knot, introduce genhdr-y that takes this into account; the sole user of objhdr-y, linux/version.h, should be migrated over at some later date. Suggested-by: David Woodhouse Acked-by: David Woodhouse Cc: Sam Ravnborg Cc: Michal Marek Signed-off-by: H. Peter Anvin diff --git a/scripts/Makefile.headersinst b/scripts/Makefile.headersinst index a57f5bd..d3bae5e 100644 --- a/scripts/Makefile.headersinst +++ b/scripts/Makefile.headersinst @@ -4,12 +4,16 @@ # header-y - list files to be installed. They are preprocessed # to remove __KERNEL__ section of the file # objhdr-y - Same as header-y but for generated files +# genhdr-y - Same as objhdr-y but in a generated/ directory # # ========================================================================== # called may set destination dir (when installing to asm/) _dst := $(if $(dst),$(dst),$(obj)) +# generated header directory +gen := $(if $(gen),$(gen),$(subst include/,include/generated/,$(obj))) + kbuild-file := $(srctree)/$(obj)/Kbuild include $(kbuild-file) @@ -33,9 +37,10 @@ wrapper-files := $(filter $(header-y), $(generic-y)) # all headers files for this dir header-y := $(filter-out $(generic-y), $(header-y)) -all-files := $(header-y) $(objhdr-y) $(wrapper-files) +all-files := $(header-y) $(objhdr-y) $(genhdr-y) $(wrapper-files) input-files := $(addprefix $(srctree)/$(obj)/,$(header-y)) \ - $(addprefix $(objtree)/$(obj)/,$(objhdr-y)) + $(addprefix $(objtree)/$(obj)/,$(objhdr-y)) \ + $(addprefix $(objtree)/$(gen)/,$(genhdr-y)) output-files := $(addprefix $(install)/, $(all-files)) # Work out what needs to be removed @@ -52,6 +57,7 @@ quiet_cmd_install = INSTALL $(printdir) ($(words $(all-files))\ cmd_install = \ $(PERL) $< $(srctree)/$(obj) $(install) $(SRCARCH) $(header-y); \ $(PERL) $< $(objtree)/$(obj) $(install) $(SRCARCH) $(objhdr-y); \ + $(PERL) $< $(objtree)/$(gen) $(install) $(SRCARCH) $(genhdr-y); \ for F in $(wrapper-files); do \ echo "\#include " > $(install)/$$F; \ done; \ -- cgit v0.10.2 From 052ad274964e613a12bf8ce7c5631f70d0bc82cc Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Thu, 17 Nov 2011 13:17:35 -0800 Subject: kbuild: Add support for an "archheaders" target Add support for an "archheaders" target. This target can generate files that need to be installed for user space by "make headers_install" or "make headers_install_all". In order to support "make headers_install_all", it must be able to run without the tree having to be configured first. Cc: David Woodhouse Cc: Sam Ravnborg Cc: Michal Marek Signed-off-by: H. Peter Anvin diff --git a/Documentation/kbuild/makefiles.txt b/Documentation/kbuild/makefiles.txt index f47cdef..ab0a984 100644 --- a/Documentation/kbuild/makefiles.txt +++ b/Documentation/kbuild/makefiles.txt @@ -33,14 +33,15 @@ This document describes the Linux kernel Makefiles. === 6 Architecture Makefiles --- 6.1 Set variables to tweak the build to the architecture - --- 6.2 Add prerequisites to archprepare: - --- 6.3 List directories to visit when descending - --- 6.4 Architecture-specific boot images - --- 6.5 Building non-kbuild targets - --- 6.6 Commands useful for building a boot image - --- 6.7 Custom kbuild commands - --- 6.8 Preprocessing linker scripts - --- 6.9 Generic header files + --- 6.2 Add prerequisites to archheaders: + --- 6.3 Add prerequisites to archprepare: + --- 6.4 List directories to visit when descending + --- 6.5 Architecture-specific boot images + --- 6.6 Building non-kbuild targets + --- 6.7 Commands useful for building a boot image + --- 6.8 Custom kbuild commands + --- 6.9 Preprocessing linker scripts + --- 6.10 Generic header files === 7 Kbuild syntax for exported headers --- 7.1 header-y @@ -252,7 +253,7 @@ more details, with real examples. This will create a library lib.a based on delay.o. For kbuild to actually recognize that there is a lib.a being built, the directory shall be listed in libs-y. - See also "6.3 List directories to visit when descending". + See also "6.4 List directories to visit when descending". Use of lib-y is normally restricted to lib/ and arch/*/lib. @@ -974,7 +975,20 @@ When kbuild executes, the following steps are followed (roughly): $(KBUILD_ARFLAGS) set by the top level Makefile to "D" (deterministic mode) if this option is supported by $(AR). ---- 6.2 Add prerequisites to archprepare: +--- 6.2 Add prerequisites to archheaders: + + The archheaders: rule is used to generate header files that + may be installed into user space by "make header_install" or + "make headers_install_all". In order to support + "make headers_install_all", this target has to be able to run + on an unconfigured tree, or a tree configured for another + architecture. + + It is run before "make archprepare" when run on the + architecture itself. + + +--- 6.3 Add prerequisites to archprepare: The archprepare: rule is used to list prerequisites that need to be built before starting to descend down in the subdirectories. @@ -990,7 +1004,7 @@ When kbuild executes, the following steps are followed (roughly): generating offset header files. ---- 6.3 List directories to visit when descending +--- 6.4 List directories to visit when descending An arch Makefile cooperates with the top Makefile to define variables which specify how to build the vmlinux file. Note that there is no @@ -1019,7 +1033,7 @@ When kbuild executes, the following steps are followed (roughly): drivers-$(CONFIG_OPROFILE) += arch/sparc64/oprofile/ ---- 6.4 Architecture-specific boot images +--- 6.5 Architecture-specific boot images An arch Makefile specifies goals that take the vmlinux file, compress it, wrap it in bootstrapping code, and copy the resulting files @@ -1070,7 +1084,7 @@ When kbuild executes, the following steps are followed (roughly): When "make" is executed without arguments, bzImage will be built. ---- 6.5 Building non-kbuild targets +--- 6.6 Building non-kbuild targets extra-y @@ -1090,7 +1104,7 @@ When kbuild executes, the following steps are followed (roughly): shall be built, but shall not be linked as part of built-in.o. ---- 6.6 Commands useful for building a boot image +--- 6.7 Commands useful for building a boot image Kbuild provides a few macros that are useful when building a boot image. @@ -1112,7 +1126,7 @@ When kbuild executes, the following steps are followed (roughly): always be built. Assignments to $(targets) are without $(obj)/ prefix. if_changed may be used in conjunction with custom commands as - defined in 6.7 "Custom kbuild commands". + defined in 6.8 "Custom kbuild commands". Note: It is a typical mistake to forget the FORCE prerequisite. Another common pitfall is that whitespace is sometimes @@ -1171,7 +1185,7 @@ When kbuild executes, the following steps are followed (roughly): $(obj)/%.dtb: $(src)/%.dts $(call cmd,dtc) ---- 6.7 Custom kbuild commands +--- 6.8 Custom kbuild commands When kbuild is executing with KBUILD_VERBOSE=0, then only a shorthand of a command is normally displayed. @@ -1198,7 +1212,7 @@ When kbuild executes, the following steps are followed (roughly): will be displayed with "make KBUILD_VERBOSE=0". ---- 6.8 Preprocessing linker scripts +--- 6.9 Preprocessing linker scripts When the vmlinux image is built, the linker script arch/$(ARCH)/kernel/vmlinux.lds is used. @@ -1228,7 +1242,7 @@ When kbuild executes, the following steps are followed (roughly): The kbuild infrastructure for *lds file are used in several architecture-specific files. ---- 6.9 Generic header files +--- 6.10 Generic header files The directory include/asm-generic contains the header files that may be shared between individual architectures. diff --git a/Makefile b/Makefile index dab8610..e5e0e07 100644 --- a/Makefile +++ b/Makefile @@ -442,7 +442,7 @@ asm-generic: no-dot-config-targets := clean mrproper distclean \ cscope gtags TAGS tags help %docs check% coccicheck \ - include/linux/version.h headers_% \ + include/linux/version.h headers_% archheaders \ kernelversion %src-pkg config-targets := 0 @@ -979,7 +979,7 @@ prepare1: prepare2 include/linux/version.h include/generated/utsrelease.h \ include/config/auto.conf $(cmd_crmodverdir) -archprepare: prepare1 scripts_basic +archprepare: archheaders prepare1 scripts_basic prepare0: archprepare FORCE $(Q)$(MAKE) $(build)=. @@ -1046,8 +1046,11 @@ hdr-inst := -rR -f $(srctree)/scripts/Makefile.headersinst obj # If we do an all arch process set dst to asm-$(hdr-arch) hdr-dst = $(if $(KBUILD_HEADERS), dst=include/asm-$(hdr-arch), dst=include/asm) +PHONY += archheaders +archheaders: + PHONY += __headers -__headers: include/linux/version.h scripts_basic asm-generic FORCE +__headers: include/linux/version.h scripts_basic asm-generic archheaders FORCE $(Q)$(MAKE) $(build)=scripts build_unifdef PHONY += headers_install_all diff --git a/scripts/headers.sh b/scripts/headers.sh index 978b42b..af1ed88 100755 --- a/scripts/headers.sh +++ b/scripts/headers.sh @@ -7,6 +7,7 @@ set -e do_command() { if [ -f ${srctree}/arch/$2/include/asm/Kbuild ]; then + make ARCH=$2 KBUILD_HEADERS=$1 archheaders make ARCH=$2 KBUILD_HEADERS=$1 headers_$1 else printf "Ignoring arch: %s\n" ${arch} -- cgit v0.10.2 From b7641d2c83aa10031bf45afd82619bfaaedcbc6f Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Fri, 11 Nov 2011 15:43:02 -0800 Subject: x86-64, syscall: Adjust comment spacing and remove typo Adjust spacing for comment so that it matches the multiline comment style used in the rest of the kernel, and remove word duplication. It is not really clear what version of gcc this refers to, but the extra & doesn't cause any harm, so there is no reason to remove it. Signed-off-by: H. Peter Anvin diff --git a/arch/x86/kernel/syscall_64.c b/arch/x86/kernel/syscall_64.c index de87d60..0edfafa 100644 --- a/arch/x86/kernel/syscall_64.c +++ b/arch/x86/kernel/syscall_64.c @@ -21,9 +21,9 @@ extern void sys_ni_syscall(void); const sys_call_ptr_t sys_call_table[__NR_syscall_max+1] = { /* - *Smells like a like a compiler bug -- it doesn't work - *when the & below is removed. - */ + * Smells like a compiler bug -- it doesn't work + * when the & below is removed. + */ [0 ... __NR_syscall_max] = &sys_ni_syscall, #include }; -- cgit v0.10.2 From e79a7fccfb2ab10f8753ac634a1c8473e870ae6c Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Fri, 11 Nov 2011 15:48:42 -0800 Subject: x86-64, ia32: Move compat_ni_syscall into C and its own file Move compat_ni_syscall out of ia32entry.S and into its own .c file. Although this is a trivial function, it is not performance-critical, and this will simplify further cleanups. Signed-off-by: H. Peter Anvin diff --git a/arch/x86/ia32/Makefile b/arch/x86/ia32/Makefile index 52d0ccf..eea9a1c 100644 --- a/arch/x86/ia32/Makefile +++ b/arch/x86/ia32/Makefile @@ -3,6 +3,7 @@ # obj-$(CONFIG_IA32_EMULATION) := ia32entry.o sys_ia32.o ia32_signal.o +obj-$(CONFIG_IA32_EMULATION) += nosyscall.o sysv-$(CONFIG_SYSVIPC) := ipc32.o obj-$(CONFIG_IA32_EMULATION) += $(sysv-y) diff --git a/arch/x86/ia32/ia32entry.S b/arch/x86/ia32/ia32entry.S index a6253ec..59538a7 100644 --- a/arch/x86/ia32/ia32entry.S +++ b/arch/x86/ia32/ia32entry.S @@ -453,9 +453,6 @@ ia32_badsys: movq $-ENOSYS,%rax jmp ia32_sysret -quiet_ni_syscall: - movq $-ENOSYS,%rax - ret CFI_ENDPROC .macro PTREGSCALL label, func, arg diff --git a/arch/x86/ia32/nosyscall.c b/arch/x86/ia32/nosyscall.c new file mode 100644 index 0000000..51ecd5b --- /dev/null +++ b/arch/x86/ia32/nosyscall.c @@ -0,0 +1,7 @@ +#include +#include + +long compat_ni_syscall(void) +{ + return -ENOSYS; +} -- cgit v0.10.2 From d5e553d6e0a4bdea43adae7373e3fa144b9a1aaa Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Fri, 11 Nov 2011 15:52:52 -0800 Subject: trace: Include in trace_syscalls.c Include into trace_syscalls.c, to allow for NR_syscalls to be automatically generated. Cc: Steven Rostedt Cc: Frederic Weisbecker Cc: Ingo Molnar Signed-off-by: H. Peter Anvin diff --git a/kernel/trace/trace_syscalls.c b/kernel/trace/trace_syscalls.c index cb65454..5f35f6f 100644 --- a/kernel/trace/trace_syscalls.c +++ b/kernel/trace/trace_syscalls.c @@ -6,6 +6,7 @@ #include #include #include +#include #include "trace_output.h" #include "trace.h" -- cgit v0.10.2 From d181764ccf6207e02abb95fb3052639b947f4833 Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Fri, 11 Nov 2011 15:55:49 -0800 Subject: x86: Machine-readable syscall tables and scripts to process them Create a simple set of syscall tables and scripts to turn them into both header files (unistd_*.h) and macros for generating the system call tables. Signed-off-by: H. Peter Anvin diff --git a/arch/x86/syscalls/Makefile b/arch/x86/syscalls/Makefile new file mode 100644 index 0000000..564b247 --- /dev/null +++ b/arch/x86/syscalls/Makefile @@ -0,0 +1,43 @@ +out := $(obj)/../include/generated/asm + +# Create output directory if not already present +_dummy := $(shell [ -d '$(out)' ] || mkdir -p '$(out)') + +syscall32 := $(srctree)/$(src)/syscall_32.tbl +syscall64 := $(srctree)/$(src)/syscall_64.tbl + +syshdr := $(srctree)/$(src)/syscallhdr.sh +systbl := $(srctree)/$(src)/syscalltbl.sh + +quiet_cmd_syshdr = SYSHDR $@ + cmd_syshdr = $(CONFIG_SHELL) '$(syshdr)' $< $@ \ + $(syshdr_abi_$(basetarget)) $(syshdr_pfx_$(basetarget)) +quiet_cmd_systbl = SYSTBL $@ + cmd_systbl = $(CONFIG_SHELL) '$(systbl)' $< $@ + +syshdr_abi_unistd_32 := i386 +$(out)/unistd_32.h: $(syscall32) $(syshdr) + $(call if_changed,syshdr) + +syshdr_abi_unistd_32_ia32 := i386 +syshdr_pfx_unistd_32_ia32 := ia32_ +$(out)/unistd_32_ia32.h: $(syscall32) $(syshdr) + $(call if_changed,syshdr) + +syshdr_abi_unistd_64 := 64 +$(out)/unistd_64.h: $(syscall64) $(syshdr) + $(call if_changed,syshdr) + +$(out)/syscalls_32.h: $(syscall32) $(systbl) + $(call if_changed,systbl) +$(out)/syscalls_64.h: $(syscall64) $(systbl) + $(call if_changed,systbl) + +syshdr-y += unistd_32.h unistd_64.h +syshdr-y += syscalls_32.h +syshdr-$(CONFIG_X86_64) += unistd_32_ia32.h +syshdr-$(CONFIG_X86_64) += syscalls_64.h + +targets += $(syshdr-y) + +all: $(addprefix $(out)/,$(targets)) diff --git a/arch/x86/syscalls/syscall_32.tbl b/arch/x86/syscalls/syscall_32.tbl new file mode 100644 index 0000000..ce98e28 --- /dev/null +++ b/arch/x86/syscalls/syscall_32.tbl @@ -0,0 +1,357 @@ +# +# 32-bit system call numbers and entry vectors +# +# The format is: +# +# +# The abi is always "i386" for this file. +# +0 i386 restart_syscall sys_restart_syscall +1 i386 exit sys_exit +2 i386 fork ptregs_fork stub32_fork +3 i386 read sys_read +4 i386 write sys_write +5 i386 open sys_open compat_sys_open +6 i386 close sys_close +7 i386 waitpid sys_waitpid sys32_waitpid +8 i386 creat sys_creat +9 i386 link sys_link +10 i386 unlink sys_unlink +11 i386 execve ptregs_execve stub32_execve +12 i386 chdir sys_chdir +13 i386 time sys_time compat_sys_time +14 i386 mknod sys_mknod +15 i386 chmod sys_chmod +16 i386 lchown sys_lchown16 +17 i386 break +18 i386 oldstat sys_stat +19 i386 lseek sys_lseek sys32_lseek +20 i386 getpid sys_getpid +21 i386 mount sys_mount compat_sys_mount +22 i386 umount sys_oldumount +23 i386 setuid sys_setuid16 +24 i386 getuid sys_getuid16 +25 i386 stime sys_stime compat_sys_stime +26 i386 ptrace sys_ptrace compat_sys_ptrace +27 i386 alarm sys_alarm +28 i386 oldfstat sys_fstat +29 i386 pause sys_pause +30 i386 utime sys_utime compat_sys_utime +31 i386 stty +32 i386 gtty +33 i386 access sys_access +34 i386 nice sys_nice +35 i386 ftime +36 i386 sync sys_sync +37 i386 kill sys_kill sys32_kill +38 i386 rename sys_rename +39 i386 mkdir sys_mkdir +40 i386 rmdir sys_rmdir +41 i386 dup sys_dup +42 i386 pipe sys_pipe +43 i386 times sys_times compat_sys_times +44 i386 prof +45 i386 brk sys_brk +46 i386 setgid sys_setgid16 +47 i386 getgid sys_getgid16 +48 i386 signal sys_signal +49 i386 geteuid sys_geteuid16 +50 i386 getegid sys_getegid16 +51 i386 acct sys_acct +52 i386 umount2 sys_umount +53 i386 lock +54 i386 ioctl sys_ioctl compat_sys_ioctl +55 i386 fcntl sys_fcntl compat_sys_fcntl64 +56 i386 mpx +57 i386 setpgid sys_setpgid +58 i386 ulimit +59 i386 oldolduname sys_olduname +60 i386 umask sys_umask +61 i386 chroot sys_chroot +62 i386 ustat sys_ustat compat_sys_ustat +63 i386 dup2 sys_dup2 +64 i386 getppid sys_getppid +65 i386 getpgrp sys_getpgrp +66 i386 setsid sys_setsid +67 i386 sigaction sys_sigaction sys32_sigaction +68 i386 sgetmask sys_sgetmask +69 i386 ssetmask sys_ssetmask +70 i386 setreuid sys_setreuid16 +71 i386 setregid sys_setregid16 +72 i386 sigsuspend sys_sigsuspend sys32_sigsuspend +73 i386 sigpending sys_sigpending compat_sys_sigpending +74 i386 sethostname sys_sethostname +75 i386 setrlimit sys_setrlimit compat_sys_setrlimit +76 i386 getrlimit sys_old_getrlimit compat_sys_old_getrlimit +77 i386 getrusage sys_getrusage compat_sys_getrusage +78 i386 gettimeofday sys_gettimeofday compat_sys_gettimeofday +79 i386 settimeofday sys_settimeofday compat_sys_settimeofday +80 i386 getgroups sys_getgroups16 +81 i386 setgroups sys_setgroups16 +82 i386 select sys_old_select compat_sys_old_select +83 i386 symlink sys_symlink +84 i386 oldlstat sys_lstat +85 i386 readlink sys_readlink +86 i386 uselib sys_uselib +87 i386 swapon sys_swapon +88 i386 reboot sys_reboot +89 i386 readdir sys_old_readdir compat_sys_old_readdir +90 i386 mmap sys_old_mmap sys32_mmap +91 i386 munmap sys_munmap +92 i386 truncate sys_truncate +93 i386 ftruncate sys_ftruncate +94 i386 fchmod sys_fchmod +95 i386 fchown sys_fchown16 +96 i386 getpriority sys_getpriority +97 i386 setpriority sys_setpriority +98 i386 profil +99 i386 statfs sys_statfs compat_sys_statfs +100 i386 fstatfs sys_fstatfs compat_sys_fstatfs +101 i386 ioperm sys_ioperm +102 i386 socketcall sys_socketcall compat_sys_socketcall +103 i386 syslog sys_syslog +104 i386 setitimer sys_setitimer compat_sys_setitimer +105 i386 getitimer sys_getitimer compat_sys_getitimer +106 i386 stat sys_newstat compat_sys_newstat +107 i386 lstat sys_newlstat compat_sys_newlstat +108 i386 fstat sys_newfstat compat_sys_newfstat +109 i386 olduname sys_uname +110 i386 iopl ptregs_iopl stub32_iopl +111 i386 vhangup sys_vhangup +112 i386 idle +113 i386 vm86old ptregs_vm86old sys32_vm86_warning +114 i386 wait4 sys_wait4 compat_sys_wait4 +115 i386 swapoff sys_swapoff +116 i386 sysinfo sys_sysinfo compat_sys_sysinfo +117 i386 ipc sys_ipc sys32_ipc +118 i386 fsync sys_fsync +119 i386 sigreturn ptregs_sigreturn stub32_sigreturn +120 i386 clone ptregs_clone stub32_clone +121 i386 setdomainname sys_setdomainname +122 i386 uname sys_newuname +123 i386 modify_ldt sys_modify_ldt +124 i386 adjtimex sys_adjtimex compat_sys_adjtimex +125 i386 mprotect sys_mprotect sys32_mprotect +126 i386 sigprocmask sys_sigprocmask compat_sys_sigprocmask +127 i386 create_module +128 i386 init_module sys_init_module +129 i386 delete_module sys_delete_module +130 i386 get_kernel_syms +131 i386 quotactl sys_quotactl sys32_quotactl +132 i386 getpgid sys_getpgid +133 i386 fchdir sys_fchdir +134 i386 bdflush sys_bdflush +135 i386 sysfs sys_sysfs +136 i386 personality sys_personality +137 i386 afs_syscall +138 i386 setfsuid sys_setfsuid16 +139 i386 setfsgid sys_setfsgid16 +140 i386 _llseek sys_llseek +141 i386 getdents sys_getdents compat_sys_getdents +142 i386 _newselect sys_select compat_sys_select +143 i386 flock sys_flock +144 i386 msync sys_msync +145 i386 readv sys_readv compat_sys_readv +146 i386 writev sys_writev compat_sys_writev +147 i386 getsid sys_getsid +148 i386 fdatasync sys_fdatasync +149 i386 _sysctl sys_sysctl compat_sys_sysctl +150 i386 mlock sys_mlock +151 i386 munlock sys_munlock +152 i386 mlockall sys_mlockall +153 i386 munlockall sys_munlockall +154 i386 sched_setparam sys_sched_setparam +155 i386 sched_getparam sys_sched_getparam +156 i386 sched_setscheduler sys_sched_setscheduler +157 i386 sched_getscheduler sys_sched_getscheduler +158 i386 sched_yield sys_sched_yield +159 i386 sched_get_priority_max sys_sched_get_priority_max +160 i386 sched_get_priority_min sys_sched_get_priority_min +161 i386 sched_rr_get_interval sys_sched_rr_get_interval sys32_sched_rr_get_interval +162 i386 nanosleep sys_nanosleep compat_sys_nanosleep +163 i386 mremap sys_mremap +164 i386 setresuid sys_setresuid16 +165 i386 getresuid sys_getresuid16 +166 i386 vm86 ptregs_vm86 sys32_vm86_warning +167 i386 query_module +168 i386 poll sys_poll +169 i386 nfsservctl +170 i386 setresgid sys_setresgid16 +171 i386 getresgid sys_getresgid16 +172 i386 prctl sys_prctl +173 i386 rt_sigreturn ptregs_rt_sigreturn stub32_rt_sigreturn +174 i386 rt_sigaction sys_rt_sigaction sys32_rt_sigaction +175 i386 rt_sigprocmask sys_rt_sigprocmask sys32_rt_sigprocmask +176 i386 rt_sigpending sys_rt_sigpending sys32_rt_sigpending +177 i386 rt_sigtimedwait sys_rt_sigtimedwait compat_sys_rt_sigtimedwait +178 i386 rt_sigqueueinfo sys_rt_sigqueueinfo sys32_rt_sigqueueinfo +179 i386 rt_sigsuspend sys_rt_sigsuspend +180 i386 pread64 sys_pread64 sys32_pread +181 i386 pwrite64 sys_pwrite64 sys32_pwrite +182 i386 chown sys_chown16 +183 i386 getcwd sys_getcwd +184 i386 capget sys_capget +185 i386 capset sys_capset +186 i386 sigaltstack ptregs_sigaltstack stub32_sigaltstack +187 i386 sendfile sys_sendfile sys32_sendfile +188 i386 getpmsg +189 i386 putpmsg +190 i386 vfork ptregs_vfork stub32_vfork +191 i386 ugetrlimit sys_getrlimit compat_sys_getrlimit +192 i386 mmap2 sys_mmap_pgoff +193 i386 truncate64 sys_truncate64 sys32_truncate64 +194 i386 ftruncate64 sys_ftruncate64 sys32_ftruncate64 +195 i386 stat64 sys_stat64 sys32_stat64 +196 i386 lstat64 sys_lstat64 sys32_lstat64 +197 i386 fstat64 sys_fstat64 sys32_fstat64 +198 i386 lchown32 sys_lchown +199 i386 getuid32 sys_getuid +200 i386 getgid32 sys_getgid +201 i386 geteuid32 sys_geteuid +202 i386 getegid32 sys_getegid +203 i386 setreuid32 sys_setreuid +204 i386 setregid32 sys_setregid +205 i386 getgroups32 sys_getgroups +206 i386 setgroups32 sys_setgroups +207 i386 fchown32 sys_fchown +208 i386 setresuid32 sys_setresuid +209 i386 getresuid32 sys_getresuid +210 i386 setresgid32 sys_setresgid +211 i386 getresgid32 sys_getresgid +212 i386 chown32 sys_chown +213 i386 setuid32 sys_setuid +214 i386 setgid32 sys_setgid +215 i386 setfsuid32 sys_setfsuid +216 i386 setfsgid32 sys_setfsgid +217 i386 pivot_root sys_pivot_root +218 i386 mincore sys_mincore +219 i386 madvise sys_madvise +220 i386 getdents64 sys_getdents64 compat_sys_getdents64 +221 i386 fcntl64 sys_fcntl64 compat_sys_fcntl64 +# 222 is unused +# 223 is unused +224 i386 gettid sys_gettid +225 i386 readahead sys_readahead sys32_readahead +226 i386 setxattr sys_setxattr +227 i386 lsetxattr sys_lsetxattr +228 i386 fsetxattr sys_fsetxattr +229 i386 getxattr sys_getxattr +230 i386 lgetxattr sys_lgetxattr +231 i386 fgetxattr sys_fgetxattr +232 i386 listxattr sys_listxattr +233 i386 llistxattr sys_llistxattr +234 i386 flistxattr sys_flistxattr +235 i386 removexattr sys_removexattr +236 i386 lremovexattr sys_lremovexattr +237 i386 fremovexattr sys_fremovexattr +238 i386 tkill sys_tkill +239 i386 sendfile64 sys_sendfile64 +240 i386 futex sys_futex compat_sys_futex +241 i386 sched_setaffinity sys_sched_setaffinity compat_sys_sched_setaffinity +242 i386 sched_getaffinity sys_sched_getaffinity compat_sys_sched_getaffinity +243 i386 set_thread_area sys_set_thread_area +244 i386 get_thread_area sys_get_thread_area +245 i386 io_setup sys_io_setup compat_sys_io_setup +246 i386 io_destroy sys_io_destroy +247 i386 io_getevents sys_io_getevents compat_sys_io_getevents +248 i386 io_submit sys_io_submit compat_sys_io_submit +249 i386 io_cancel sys_io_cancel +250 i386 fadvise64 sys_fadvise64 sys32_fadvise64 +# 251 is available for reuse (was briefly sys_set_zone_reclaim) +252 i386 exit_group sys_exit_group +253 i386 lookup_dcookie sys_lookup_dcookie sys32_lookup_dcookie +254 i386 epoll_create sys_epoll_create +255 i386 epoll_ctl sys_epoll_ctl +256 i386 epoll_wait sys_epoll_wait +257 i386 remap_file_pages sys_remap_file_pages +258 i386 set_tid_address sys_set_tid_address +259 i386 timer_create sys_timer_create compat_sys_timer_create +260 i386 timer_settime sys_timer_settime compat_sys_timer_settime +261 i386 timer_gettime sys_timer_gettime compat_sys_timer_gettime +262 i386 timer_getoverrun sys_timer_getoverrun +263 i386 timer_delete sys_timer_delete +264 i386 clock_settime sys_clock_settime compat_sys_clock_settime +265 i386 clock_gettime sys_clock_gettime compat_sys_clock_gettime +266 i386 clock_getres sys_clock_getres compat_sys_clock_getres +267 i386 clock_nanosleep sys_clock_nanosleep compat_sys_clock_nanosleep +268 i386 statfs64 sys_statfs64 compat_sys_statfs64 +269 i386 fstatfs64 sys_fstatfs64 compat_sys_fstatfs64 +270 i386 tgkill sys_tgkill +271 i386 utimes sys_utimes compat_sys_utimes +272 i386 fadvise64_64 sys_fadvise64_64 sys32_fadvise64_64 +273 i386 vserver +274 i386 mbind sys_mbind +275 i386 get_mempolicy sys_get_mempolicy compat_sys_get_mempolicy +276 i386 set_mempolicy sys_set_mempolicy +277 i386 mq_open sys_mq_open compat_sys_mq_open +278 i386 mq_unlink sys_mq_unlink +279 i386 mq_timedsend sys_mq_timedsend compat_sys_mq_timedsend +280 i386 mq_timedreceive sys_mq_timedreceive compat_sys_mq_timedreceive +281 i386 mq_notify sys_mq_notify compat_sys_mq_notify +282 i386 mq_getsetaddr sys_mq_getsetattr compat_sys_mq_getsetattr +283 i386 kexec_load sys_kexec_load compat_sys_kexec_load +284 i386 waitid sys_waitid compat_sys_waitid +# 285 sys_setaltroot +286 i386 add_key sys_add_key +287 i386 request_key sys_request_key +288 i386 keyctl sys_keyctl +289 i386 ioprio_set sys_ioprio_set +290 i386 ioprio_get sys_ioprio_get +291 i386 inotify_init sys_inotify_init +292 i386 inotify_add_watch sys_inotify_add_watch +293 i386 inotify_rm_watch sys_inotify_rm_watch +294 i386 migrate_pages sys_migrate_pages +295 i386 openat sys_openat compat_sys_openat +296 i386 mkdirat sys_mkdirat +297 i386 mknodat sys_mknodat +298 i386 fchownat sys_fchownat +299 i386 futimesat sys_futimesat compat_sys_futimesat +300 i386 fstatat64 sys_fstatat64 sys32_fstatat +301 i386 unlinkat sys_unlinkat +302 i386 renameat sys_renameat +303 i386 linkat sys_linkat +304 i386 symlinkat sys_symlinkat +305 i386 readlinkat sys_readlinkat +306 i386 fchmodat sys_fchmodat +307 i386 faccessat sys_faccessat +308 i386 pselect6 sys_pselect6 compat_sys_pselect6 +309 i386 ppoll sys_ppoll compat_sys_ppoll +310 i386 unshare sys_unshare +311 i386 set_robust_list sys_set_robust_list compat_sys_set_robust_list +312 i386 get_robust_list sys_get_robust_list compat_sys_get_robust_list +313 i386 splice sys_splice +314 i386 sync_file_range sys_sync_file_range sys32_sync_file_range +315 i386 tee sys_tee +316 i386 vmsplice sys_vmsplice compat_sys_vmsplice +317 i386 move_pages sys_move_pages compat_sys_move_pages +318 i386 getcpu sys_getcpu +319 i386 epoll_pwait sys_epoll_pwait +320 i386 utimensat sys_utimensat compat_sys_utimensat +321 i386 signalfd sys_signalfd compat_sys_signalfd +322 i386 timerfd_create sys_timerfd_create +323 i386 eventfd sys_eventfd +324 i386 fallocate sys_fallocate sys32_fallocate +325 i386 timerfd_settime sys_timerfd_settime compat_sys_timerfd_settime +326 i386 timerfd_gettime sys_timerfd_gettime compat_sys_timerfd_gettime +327 i386 signalfd4 sys_signalfd4 compat_sys_signalfd4 +328 i386 eventfd2 sys_eventfd2 +329 i386 epoll_create1 sys_epoll_create1 +330 i386 dup3 sys_dup3 +331 i386 pipe2 sys_pipe2 +332 i386 inotify_init1 sys_inotify_init1 +333 i386 preadv sys_preadv compat_sys_preadv +334 i386 pwritev sys_pwritev compat_sys_pwritev +335 i386 rt_tgsigqueueinfo sys_rt_tgsigqueueinfo compat_sys_rt_tgsigqueueinfo +336 i386 perf_event_open sys_perf_event_open +337 i386 recvmmsg sys_recvmmsg compat_sys_recvmmsg +338 i386 fanotify_init sys_fanotify_init +339 i386 fanotify_mark sys_fanotify_mark sys32_fanotify_mark +340 i386 prlimit64 sys_prlimit64 +341 i386 name_to_handle_at sys_name_to_handle_at +342 i386 open_by_handle_at sys_open_by_handle_at compat_sys_open_by_handle_at +343 i386 clock_adjtime sys_clock_adjtime compat_sys_clock_adjtime +344 i386 syncfs sys_syncfs +345 i386 sendmmsg sys_sendmmsg compat_sys_sendmmsg +346 i386 setns sys_setns +347 i386 process_vm_readv sys_process_vm_readv compat_sys_process_vm_readv +348 i386 process_vm_writev sys_process_vm_writev compat_sys_process_vm_writev diff --git a/arch/x86/syscalls/syscall_64.tbl b/arch/x86/syscalls/syscall_64.tbl new file mode 100644 index 0000000..b440a8f --- /dev/null +++ b/arch/x86/syscalls/syscall_64.tbl @@ -0,0 +1,320 @@ +# +# 64-bit system call numbers and entry vectors +# +# The format is: +# +# +# The abi is always "64" for this file (for now.) +# +0 64 read sys_read +1 64 write sys_write +2 64 open sys_open +3 64 close sys_close +4 64 stat sys_newstat +5 64 fstat sys_newfstat +6 64 lstat sys_newlstat +7 64 poll sys_poll +8 64 lseek sys_lseek +9 64 mmap sys_mmap +10 64 mprotect sys_mprotect +11 64 munmap sys_munmap +12 64 brk sys_brk +13 64 rt_sigaction sys_rt_sigaction +14 64 rt_sigprocmask sys_rt_sigprocmask +15 64 rt_sigreturn stub_rt_sigreturn +16 64 ioctl sys_ioctl +17 64 pread64 sys_pread64 +18 64 pwrite64 sys_pwrite64 +19 64 readv sys_readv +20 64 writev sys_writev +21 64 access sys_access +22 64 pipe sys_pipe +23 64 select sys_select +24 64 sched_yield sys_sched_yield +25 64 mremap sys_mremap +26 64 msync sys_msync +27 64 mincore sys_mincore +28 64 madvise sys_madvise +29 64 shmget sys_shmget +30 64 shmat sys_shmat +31 64 shmctl sys_shmctl +32 64 dup sys_dup +33 64 dup2 sys_dup2 +34 64 pause sys_pause +35 64 nanosleep sys_nanosleep +36 64 getitimer sys_getitimer +37 64 alarm sys_alarm +38 64 setitimer sys_setitimer +39 64 getpid sys_getpid +40 64 sendfile sys_sendfile64 +41 64 socket sys_socket +42 64 connect sys_connect +43 64 accept sys_accept +44 64 sendto sys_sendto +45 64 recvfrom sys_recvfrom +46 64 sendmsg sys_sendmsg +47 64 recvmsg sys_recvmsg +48 64 shutdown sys_shutdown +49 64 bind sys_bind +50 64 listen sys_listen +51 64 getsockname sys_getsockname +52 64 getpeername sys_getpeername +53 64 socketpair sys_socketpair +54 64 setsockopt sys_setsockopt +55 64 getsockopt sys_getsockopt +56 64 clone stub_clone +57 64 fork stub_fork +58 64 vfork stub_vfork +59 64 execve stub_execve +60 64 exit sys_exit +61 64 wait4 sys_wait4 +62 64 kill sys_kill +63 64 uname sys_newuname +64 64 semget sys_semget +65 64 semop sys_semop +66 64 semctl sys_semctl +67 64 shmdt sys_shmdt +68 64 msgget sys_msgget +69 64 msgsnd sys_msgsnd +70 64 msgrcv sys_msgrcv +71 64 msgctl sys_msgctl +72 64 fcntl sys_fcntl +73 64 flock sys_flock +74 64 fsync sys_fsync +75 64 fdatasync sys_fdatasync +76 64 truncate sys_truncate +77 64 ftruncate sys_ftruncate +78 64 getdents sys_getdents +79 64 getcwd sys_getcwd +80 64 chdir sys_chdir +81 64 fchdir sys_fchdir +82 64 rename sys_rename +83 64 mkdir sys_mkdir +84 64 rmdir sys_rmdir +85 64 creat sys_creat +86 64 link sys_link +87 64 unlink sys_unlink +88 64 symlink sys_symlink +89 64 readlink sys_readlink +90 64 chmod sys_chmod +91 64 fchmod sys_fchmod +92 64 chown sys_chown +93 64 fchown sys_fchown +94 64 lchown sys_lchown +95 64 umask sys_umask +96 64 gettimeofday sys_gettimeofday +97 64 getrlimit sys_getrlimit +98 64 getrusage sys_getrusage +99 64 sysinfo sys_sysinfo +100 64 times sys_times +101 64 ptrace sys_ptrace +102 64 getuid sys_getuid +103 64 syslog sys_syslog +104 64 getgid sys_getgid +105 64 setuid sys_setuid +106 64 setgid sys_setgid +107 64 geteuid sys_geteuid +108 64 getegid sys_getegid +109 64 setpgid sys_setpgid +110 64 getppid sys_getppid +111 64 getpgrp sys_getpgrp +112 64 setsid sys_setsid +113 64 setreuid sys_setreuid +114 64 setregid sys_setregid +115 64 getgroups sys_getgroups +116 64 setgroups sys_setgroups +117 64 setresuid sys_setresuid +118 64 getresuid sys_getresuid +119 64 setresgid sys_setresgid +120 64 getresgid sys_getresgid +121 64 getpgid sys_getpgid +122 64 setfsuid sys_setfsuid +123 64 setfsgid sys_setfsgid +124 64 getsid sys_getsid +125 64 capget sys_capget +126 64 capset sys_capset +127 64 rt_sigpending sys_rt_sigpending +128 64 rt_sigtimedwait sys_rt_sigtimedwait +129 64 rt_sigqueueinfo sys_rt_sigqueueinfo +130 64 rt_sigsuspend sys_rt_sigsuspend +131 64 sigaltstack stub_sigaltstack +132 64 utime sys_utime +133 64 mknod sys_mknod +134 64 uselib +135 64 personality sys_personality +136 64 ustat sys_ustat +137 64 statfs sys_statfs +138 64 fstatfs sys_fstatfs +139 64 sysfs sys_sysfs +140 64 getpriority sys_getpriority +141 64 setpriority sys_setpriority +142 64 sched_setparam sys_sched_setparam +143 64 sched_getparam sys_sched_getparam +144 64 sched_setscheduler sys_sched_setscheduler +145 64 sched_getscheduler sys_sched_getscheduler +146 64 sched_get_priority_max sys_sched_get_priority_max +147 64 sched_get_priority_min sys_sched_get_priority_min +148 64 sched_rr_get_interval sys_sched_rr_get_interval +149 64 mlock sys_mlock +150 64 munlock sys_munlock +151 64 mlockall sys_mlockall +152 64 munlockall sys_munlockall +153 64 vhangup sys_vhangup +154 64 modify_ldt sys_modify_ldt +155 64 pivot_root sys_pivot_root +156 64 _sysctl sys_sysctl +157 64 prctl sys_prctl +158 64 arch_prctl sys_arch_prctl +159 64 adjtimex sys_adjtimex +160 64 setrlimit sys_setrlimit +161 64 chroot sys_chroot +162 64 sync sys_sync +163 64 acct sys_acct +164 64 settimeofday sys_settimeofday +165 64 mount sys_mount +166 64 umount2 sys_umount +167 64 swapon sys_swapon +168 64 swapoff sys_swapoff +169 64 reboot sys_reboot +170 64 sethostname sys_sethostname +171 64 setdomainname sys_setdomainname +172 64 iopl stub_iopl +173 64 ioperm sys_ioperm +174 64 create_module +175 64 init_module sys_init_module +176 64 delete_module sys_delete_module +177 64 get_kernel_syms +178 64 query_module +179 64 quotactl sys_quotactl +180 64 nfsservctl +181 64 getpmsg +182 64 putpmsg +183 64 afs_syscall +184 64 tuxcall +185 64 security +186 64 gettid sys_gettid +187 64 readahead sys_readahead +188 64 setxattr sys_setxattr +189 64 lsetxattr sys_lsetxattr +190 64 fsetxattr sys_fsetxattr +191 64 getxattr sys_getxattr +192 64 lgetxattr sys_lgetxattr +193 64 fgetxattr sys_fgetxattr +194 64 listxattr sys_listxattr +195 64 llistxattr sys_llistxattr +196 64 flistxattr sys_flistxattr +197 64 removexattr sys_removexattr +198 64 lremovexattr sys_lremovexattr +199 64 fremovexattr sys_fremovexattr +200 64 tkill sys_tkill +201 64 time sys_time +202 64 futex sys_futex +203 64 sched_setaffinity sys_sched_setaffinity +204 64 sched_getaffinity sys_sched_getaffinity +205 64 set_thread_area +206 64 io_setup sys_io_setup +207 64 io_destroy sys_io_destroy +208 64 io_getevents sys_io_getevents +209 64 io_submit sys_io_submit +210 64 io_cancel sys_io_cancel +211 64 get_thread_area +212 64 lookup_dcookie sys_lookup_dcookie +213 64 epoll_create sys_epoll_create +214 64 epoll_ctl_old +215 64 epoll_wait_old +216 64 remap_file_pages sys_remap_file_pages +217 64 getdents64 sys_getdents64 +218 64 set_tid_address sys_set_tid_address +219 64 restart_syscall sys_restart_syscall +220 64 semtimedop sys_semtimedop +221 64 fadvise64 sys_fadvise64 +222 64 timer_create sys_timer_create +223 64 timer_settime sys_timer_settime +224 64 timer_gettime sys_timer_gettime +225 64 timer_getoverrun sys_timer_getoverrun +226 64 timer_delete sys_timer_delete +227 64 clock_settime sys_clock_settime +228 64 clock_gettime sys_clock_gettime +229 64 clock_getres sys_clock_getres +230 64 clock_nanosleep sys_clock_nanosleep +231 64 exit_group sys_exit_group +232 64 epoll_wait sys_epoll_wait +233 64 epoll_ctl sys_epoll_ctl +234 64 tgkill sys_tgkill +235 64 utimes sys_utimes +236 64 vserver +237 64 mbind sys_mbind +238 64 set_mempolicy sys_set_mempolicy +239 64 get_mempolicy sys_get_mempolicy +240 64 mq_open sys_mq_open +241 64 mq_unlink sys_mq_unlink +242 64 mq_timedsend sys_mq_timedsend +243 64 mq_timedreceive sys_mq_timedreceive +244 64 mq_notify sys_mq_notify +245 64 mq_getsetattr sys_mq_getsetattr +246 64 kexec_load sys_kexec_load +247 64 waitid sys_waitid +248 64 add_key sys_add_key +249 64 request_key sys_request_key +250 64 keyctl sys_keyctl +251 64 ioprio_set sys_ioprio_set +252 64 ioprio_get sys_ioprio_get +253 64 inotify_init sys_inotify_init +254 64 inotify_add_watch sys_inotify_add_watch +255 64 inotify_rm_watch sys_inotify_rm_watch +256 64 migrate_pages sys_migrate_pages +257 64 openat sys_openat +258 64 mkdirat sys_mkdirat +259 64 mknodat sys_mknodat +260 64 fchownat sys_fchownat +261 64 futimesat sys_futimesat +262 64 newfstatat sys_newfstatat +263 64 unlinkat sys_unlinkat +264 64 renameat sys_renameat +265 64 linkat sys_linkat +266 64 symlinkat sys_symlinkat +267 64 readlinkat sys_readlinkat +268 64 fchmodat sys_fchmodat +269 64 faccessat sys_faccessat +270 64 pselect6 sys_pselect6 +271 64 ppoll sys_ppoll +272 64 unshare sys_unshare +273 64 set_robust_list sys_set_robust_list +274 64 get_robust_list sys_get_robust_list +275 64 splice sys_splice +276 64 tee sys_tee +277 64 sync_file_range sys_sync_file_range +278 64 vmsplice sys_vmsplice +279 64 move_pages sys_move_pages +280 64 utimensat sys_utimensat +281 64 epoll_pwait sys_epoll_pwait +282 64 signalfd sys_signalfd +283 64 timerfd_create sys_timerfd_create +284 64 eventfd sys_eventfd +285 64 fallocate sys_fallocate +286 64 timerfd_settime sys_timerfd_settime +287 64 timerfd_gettime sys_timerfd_gettime +288 64 accept4 sys_accept4 +289 64 signalfd4 sys_signalfd4 +290 64 eventfd2 sys_eventfd2 +291 64 epoll_create1 sys_epoll_create1 +292 64 dup3 sys_dup3 +293 64 pipe2 sys_pipe2 +294 64 inotify_init1 sys_inotify_init1 +295 64 preadv sys_preadv +296 64 pwritev sys_pwritev +297 64 rt_tgsigqueueinfo sys_rt_tgsigqueueinfo +298 64 perf_event_open sys_perf_event_open +299 64 recvmmsg sys_recvmmsg +300 64 fanotify_init sys_fanotify_init +301 64 fanotify_mark sys_fanotify_mark +302 64 prlimit64 sys_prlimit64 +303 64 name_to_handle_at sys_name_to_handle_at +304 64 open_by_handle_at sys_open_by_handle_at +305 64 clock_adjtime sys_clock_adjtime +306 64 syncfs sys_syncfs +307 64 sendmmsg sys_sendmmsg +308 64 setns sys_setns +309 64 getcpu sys_getcpu +310 64 process_vm_readv sys_process_vm_readv +311 64 process_vm_writev sys_process_vm_writev diff --git a/arch/x86/syscalls/syscallhdr.sh b/arch/x86/syscalls/syscallhdr.sh new file mode 100644 index 0000000..0d473ff --- /dev/null +++ b/arch/x86/syscalls/syscallhdr.sh @@ -0,0 +1,36 @@ +#!/bin/sh + +in="$1" +out="$2" +my_abis=`echo "$3" | tr ',' ' '` +prefix="$4" +offset="$5" + +fileguard=_ASM_X86_`basename "$out" | sed \ + -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/' \ + -e 's/[^A-Z0-9_]/_/g' -e 's/__/_/g'` + +in_list () { + local x + for x in $1; do + if [ x"$x" = x"$2" ]; then + return 0 + fi + done + return 1 +} + +grep '^[0-9]' "$in" | sort -n | ( + echo "#ifndef ${fileguard}" + echo "#define ${fileguard} 1" + echo "" + + while read nr abi name entry ; do + if in_list "$my_abis" "$abi"; then + echo "#define __NR_${prefix}${name}" $((nr+offset)) + fi + done + + echo "" + echo "#endif /* ${fileguard} */" +) > "$out" diff --git a/arch/x86/syscalls/syscalltbl.sh b/arch/x86/syscalls/syscalltbl.sh new file mode 100644 index 0000000..0e7f8ec --- /dev/null +++ b/arch/x86/syscalls/syscalltbl.sh @@ -0,0 +1,15 @@ +#!/bin/sh + +in="$1" +out="$2" + +grep '^[0-9]' "$in" | sort -n | ( + while read nr abi name entry compat; do + abi=`echo "$abi" | tr '[a-z]' '[A-Z]'` + if [ -n "$compat" ]; then + echo "__SYSCALL_${abi}($nr, $entry, $compat)" + elif [ -n "$entry" ]; then + echo "__SYSCALL_${abi}($nr, $entry, $entry)" + fi + done +) > "$out" -- cgit v0.10.2 From 29dc54c673ea2531d589400badb4ada5f5f60dae Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Fri, 11 Nov 2011 15:57:53 -0800 Subject: checksyscalls: Use arch/x86/syscalls/syscall_32.tbl as source Use the new arch/x86/syscalls/syscall_32.tbl file as source instead of arch/x86/include/asm/unistd_32.h. Cc: Michal Marek Cc: Geert Uytterhoeven Cc: Sam Ravnborg Signed-off-by: H. Peter Anvin diff --git a/scripts/checksyscalls.sh b/scripts/checksyscalls.sh index 3ab316e..d24810f 100755 --- a/scripts/checksyscalls.sh +++ b/scripts/checksyscalls.sh @@ -198,11 +198,16 @@ EOF } syscall_list() { -sed -n -e '/^\#define/ s/[^_]*__NR_\([^[:space:]]*\).*/\ -\#if !defined \(__NR_\1\) \&\& !defined \(__IGNORE_\1\)\ -\#warning syscall \1 not implemented\ -\#endif/p' $1 + grep '^[0-9]' "$1" | sort -n | ( + while read nr abi name entry ; do + echo < /dev/null -- cgit v0.10.2 From 303395ac3bf3e2cb488435537d416bc840438fcb Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Fri, 11 Nov 2011 16:07:41 -0800 Subject: x86: Generate system call tables and unistd_*.h from tables Generate system call tables and unistd_*.h automatically from the tables in arch/x86/syscalls. All other information, like NR_syscalls, is auto-generated, some of which is in asm-offsets_*.c. This allows us to keep all the system call information in one place, and allows for kernel space and user space to see different information; this is currently used for the ia32 system call numbers when building the 64-bit kernel, but will be used by the x32 ABI in the near future. This also removes some gratuitious differences between i386, x86-64 and ia32; in particular, now all system call tables are generated with the same mechanism. Cc: H. J. Lu Cc: Sam Ravnborg Cc: Michal Marek Signed-off-by: H. Peter Anvin diff --git a/arch/x86/Makefile b/arch/x86/Makefile index b02e509..209ba12 100644 --- a/arch/x86/Makefile +++ b/arch/x86/Makefile @@ -118,6 +118,12 @@ KBUILD_CFLAGS += $(mflags-y) KBUILD_AFLAGS += $(mflags-y) ### +# Syscall table generation + +archheaders: + $(Q)$(MAKE) $(build)=arch/x86/syscalls all + +### # Kernel objects head-y := arch/x86/kernel/head_$(BITS).o diff --git a/arch/x86/ia32/Makefile b/arch/x86/ia32/Makefile index eea9a1c..455646e 100644 --- a/arch/x86/ia32/Makefile +++ b/arch/x86/ia32/Makefile @@ -3,7 +3,7 @@ # obj-$(CONFIG_IA32_EMULATION) := ia32entry.o sys_ia32.o ia32_signal.o -obj-$(CONFIG_IA32_EMULATION) += nosyscall.o +obj-$(CONFIG_IA32_EMULATION) += nosyscall.o syscall_ia32.o sysv-$(CONFIG_SYSVIPC) := ipc32.o obj-$(CONFIG_IA32_EMULATION) += $(sysv-y) diff --git a/arch/x86/ia32/ia32entry.S b/arch/x86/ia32/ia32entry.S index 59538a7..72f853a 100644 --- a/arch/x86/ia32/ia32entry.S +++ b/arch/x86/ia32/ia32entry.S @@ -27,8 +27,6 @@ .section .entry.text, "ax" -#define IA32_NR_syscalls ((ia32_syscall_end - ia32_sys_call_table)/8) - .macro IA32_ARG_FIXUP noebp=0 movl %edi,%r8d .if \noebp @@ -496,357 +494,3 @@ ENTRY(ia32_ptregs_common) jmp ia32_sysret /* misbalances the return cache */ CFI_ENDPROC END(ia32_ptregs_common) - - .section .rodata,"a" - .align 8 -ia32_sys_call_table: - .quad sys_restart_syscall - .quad sys_exit - .quad stub32_fork - .quad sys_read - .quad sys_write - .quad compat_sys_open /* 5 */ - .quad sys_close - .quad sys32_waitpid - .quad sys_creat - .quad sys_link - .quad sys_unlink /* 10 */ - .quad stub32_execve - .quad sys_chdir - .quad compat_sys_time - .quad sys_mknod - .quad sys_chmod /* 15 */ - .quad sys_lchown16 - .quad quiet_ni_syscall /* old break syscall holder */ - .quad sys_stat - .quad sys32_lseek - .quad sys_getpid /* 20 */ - .quad compat_sys_mount /* mount */ - .quad sys_oldumount /* old_umount */ - .quad sys_setuid16 - .quad sys_getuid16 - .quad compat_sys_stime /* stime */ /* 25 */ - .quad compat_sys_ptrace /* ptrace */ - .quad sys_alarm - .quad sys_fstat /* (old)fstat */ - .quad sys_pause - .quad compat_sys_utime /* 30 */ - .quad quiet_ni_syscall /* old stty syscall holder */ - .quad quiet_ni_syscall /* old gtty syscall holder */ - .quad sys_access - .quad sys_nice - .quad quiet_ni_syscall /* 35 */ /* old ftime syscall holder */ - .quad sys_sync - .quad sys32_kill - .quad sys_rename - .quad sys_mkdir - .quad sys_rmdir /* 40 */ - .quad sys_dup - .quad sys_pipe - .quad compat_sys_times - .quad quiet_ni_syscall /* old prof syscall holder */ - .quad sys_brk /* 45 */ - .quad sys_setgid16 - .quad sys_getgid16 - .quad sys_signal - .quad sys_geteuid16 - .quad sys_getegid16 /* 50 */ - .quad sys_acct - .quad sys_umount /* new_umount */ - .quad quiet_ni_syscall /* old lock syscall holder */ - .quad compat_sys_ioctl - .quad compat_sys_fcntl64 /* 55 */ - .quad quiet_ni_syscall /* old mpx syscall holder */ - .quad sys_setpgid - .quad quiet_ni_syscall /* old ulimit syscall holder */ - .quad sys_olduname - .quad sys_umask /* 60 */ - .quad sys_chroot - .quad compat_sys_ustat - .quad sys_dup2 - .quad sys_getppid - .quad sys_getpgrp /* 65 */ - .quad sys_setsid - .quad sys32_sigaction - .quad sys_sgetmask - .quad sys_ssetmask - .quad sys_setreuid16 /* 70 */ - .quad sys_setregid16 - .quad sys32_sigsuspend - .quad compat_sys_sigpending - .quad sys_sethostname - .quad compat_sys_setrlimit /* 75 */ - .quad compat_sys_old_getrlimit /* old_getrlimit */ - .quad compat_sys_getrusage - .quad compat_sys_gettimeofday - .quad compat_sys_settimeofday - .quad sys_getgroups16 /* 80 */ - .quad sys_setgroups16 - .quad compat_sys_old_select - .quad sys_symlink - .quad sys_lstat - .quad sys_readlink /* 85 */ - .quad sys_uselib - .quad sys_swapon - .quad sys_reboot - .quad compat_sys_old_readdir - .quad sys32_mmap /* 90 */ - .quad sys_munmap - .quad sys_truncate - .quad sys_ftruncate - .quad sys_fchmod - .quad sys_fchown16 /* 95 */ - .quad sys_getpriority - .quad sys_setpriority - .quad quiet_ni_syscall /* old profil syscall holder */ - .quad compat_sys_statfs - .quad compat_sys_fstatfs /* 100 */ - .quad sys_ioperm - .quad compat_sys_socketcall - .quad sys_syslog - .quad compat_sys_setitimer - .quad compat_sys_getitimer /* 105 */ - .quad compat_sys_newstat - .quad compat_sys_newlstat - .quad compat_sys_newfstat - .quad sys_uname - .quad stub32_iopl /* 110 */ - .quad sys_vhangup - .quad quiet_ni_syscall /* old "idle" system call */ - .quad sys32_vm86_warning /* vm86old */ - .quad compat_sys_wait4 - .quad sys_swapoff /* 115 */ - .quad compat_sys_sysinfo - .quad sys32_ipc - .quad sys_fsync - .quad stub32_sigreturn - .quad stub32_clone /* 120 */ - .quad sys_setdomainname - .quad sys_newuname - .quad sys_modify_ldt - .quad compat_sys_adjtimex - .quad sys32_mprotect /* 125 */ - .quad compat_sys_sigprocmask - .quad quiet_ni_syscall /* create_module */ - .quad sys_init_module - .quad sys_delete_module - .quad quiet_ni_syscall /* 130 get_kernel_syms */ - .quad sys32_quotactl - .quad sys_getpgid - .quad sys_fchdir - .quad quiet_ni_syscall /* bdflush */ - .quad sys_sysfs /* 135 */ - .quad sys_personality - .quad quiet_ni_syscall /* for afs_syscall */ - .quad sys_setfsuid16 - .quad sys_setfsgid16 - .quad sys_llseek /* 140 */ - .quad compat_sys_getdents - .quad compat_sys_select - .quad sys_flock - .quad sys_msync - .quad compat_sys_readv /* 145 */ - .quad compat_sys_writev - .quad sys_getsid - .quad sys_fdatasync - .quad compat_sys_sysctl /* sysctl */ - .quad sys_mlock /* 150 */ - .quad sys_munlock - .quad sys_mlockall - .quad sys_munlockall - .quad sys_sched_setparam - .quad sys_sched_getparam /* 155 */ - .quad sys_sched_setscheduler - .quad sys_sched_getscheduler - .quad sys_sched_yield - .quad sys_sched_get_priority_max - .quad sys_sched_get_priority_min /* 160 */ - .quad sys32_sched_rr_get_interval - .quad compat_sys_nanosleep - .quad sys_mremap - .quad sys_setresuid16 - .quad sys_getresuid16 /* 165 */ - .quad sys32_vm86_warning /* vm86 */ - .quad quiet_ni_syscall /* query_module */ - .quad sys_poll - .quad quiet_ni_syscall /* old nfsservctl */ - .quad sys_setresgid16 /* 170 */ - .quad sys_getresgid16 - .quad sys_prctl - .quad stub32_rt_sigreturn - .quad sys32_rt_sigaction - .quad sys32_rt_sigprocmask /* 175 */ - .quad sys32_rt_sigpending - .quad compat_sys_rt_sigtimedwait - .quad sys32_rt_sigqueueinfo - .quad sys_rt_sigsuspend - .quad sys32_pread /* 180 */ - .quad sys32_pwrite - .quad sys_chown16 - .quad sys_getcwd - .quad sys_capget - .quad sys_capset - .quad stub32_sigaltstack - .quad sys32_sendfile - .quad quiet_ni_syscall /* streams1 */ - .quad quiet_ni_syscall /* streams2 */ - .quad stub32_vfork /* 190 */ - .quad compat_sys_getrlimit - .quad sys_mmap_pgoff - .quad sys32_truncate64 - .quad sys32_ftruncate64 - .quad sys32_stat64 /* 195 */ - .quad sys32_lstat64 - .quad sys32_fstat64 - .quad sys_lchown - .quad sys_getuid - .quad sys_getgid /* 200 */ - .quad sys_geteuid - .quad sys_getegid - .quad sys_setreuid - .quad sys_setregid - .quad sys_getgroups /* 205 */ - .quad sys_setgroups - .quad sys_fchown - .quad sys_setresuid - .quad sys_getresuid - .quad sys_setresgid /* 210 */ - .quad sys_getresgid - .quad sys_chown - .quad sys_setuid - .quad sys_setgid - .quad sys_setfsuid /* 215 */ - .quad sys_setfsgid - .quad sys_pivot_root - .quad sys_mincore - .quad sys_madvise - .quad compat_sys_getdents64 /* 220 getdents64 */ - .quad compat_sys_fcntl64 - .quad quiet_ni_syscall /* tux */ - .quad quiet_ni_syscall /* security */ - .quad sys_gettid - .quad sys32_readahead /* 225 */ - .quad sys_setxattr - .quad sys_lsetxattr - .quad sys_fsetxattr - .quad sys_getxattr - .quad sys_lgetxattr /* 230 */ - .quad sys_fgetxattr - .quad sys_listxattr - .quad sys_llistxattr - .quad sys_flistxattr - .quad sys_removexattr /* 235 */ - .quad sys_lremovexattr - .quad sys_fremovexattr - .quad sys_tkill - .quad sys_sendfile64 - .quad compat_sys_futex /* 240 */ - .quad compat_sys_sched_setaffinity - .quad compat_sys_sched_getaffinity - .quad sys_set_thread_area - .quad sys_get_thread_area - .quad compat_sys_io_setup /* 245 */ - .quad sys_io_destroy - .quad compat_sys_io_getevents - .quad compat_sys_io_submit - .quad sys_io_cancel - .quad sys32_fadvise64 /* 250 */ - .quad quiet_ni_syscall /* free_huge_pages */ - .quad sys_exit_group - .quad sys32_lookup_dcookie - .quad sys_epoll_create - .quad sys_epoll_ctl /* 255 */ - .quad sys_epoll_wait - .quad sys_remap_file_pages - .quad sys_set_tid_address - .quad compat_sys_timer_create - .quad compat_sys_timer_settime /* 260 */ - .quad compat_sys_timer_gettime - .quad sys_timer_getoverrun - .quad sys_timer_delete - .quad compat_sys_clock_settime - .quad compat_sys_clock_gettime /* 265 */ - .quad compat_sys_clock_getres - .quad compat_sys_clock_nanosleep - .quad compat_sys_statfs64 - .quad compat_sys_fstatfs64 - .quad sys_tgkill /* 270 */ - .quad compat_sys_utimes - .quad sys32_fadvise64_64 - .quad quiet_ni_syscall /* sys_vserver */ - .quad sys_mbind - .quad compat_sys_get_mempolicy /* 275 */ - .quad sys_set_mempolicy - .quad compat_sys_mq_open - .quad sys_mq_unlink - .quad compat_sys_mq_timedsend - .quad compat_sys_mq_timedreceive /* 280 */ - .quad compat_sys_mq_notify - .quad compat_sys_mq_getsetattr - .quad compat_sys_kexec_load /* reserved for kexec */ - .quad compat_sys_waitid - .quad quiet_ni_syscall /* 285: sys_altroot */ - .quad sys_add_key - .quad sys_request_key - .quad sys_keyctl - .quad sys_ioprio_set - .quad sys_ioprio_get /* 290 */ - .quad sys_inotify_init - .quad sys_inotify_add_watch - .quad sys_inotify_rm_watch - .quad sys_migrate_pages - .quad compat_sys_openat /* 295 */ - .quad sys_mkdirat - .quad sys_mknodat - .quad sys_fchownat - .quad compat_sys_futimesat - .quad sys32_fstatat /* 300 */ - .quad sys_unlinkat - .quad sys_renameat - .quad sys_linkat - .quad sys_symlinkat - .quad sys_readlinkat /* 305 */ - .quad sys_fchmodat - .quad sys_faccessat - .quad compat_sys_pselect6 - .quad compat_sys_ppoll - .quad sys_unshare /* 310 */ - .quad compat_sys_set_robust_list - .quad compat_sys_get_robust_list - .quad sys_splice - .quad sys32_sync_file_range - .quad sys_tee /* 315 */ - .quad compat_sys_vmsplice - .quad compat_sys_move_pages - .quad sys_getcpu - .quad sys_epoll_pwait - .quad compat_sys_utimensat /* 320 */ - .quad compat_sys_signalfd - .quad sys_timerfd_create - .quad sys_eventfd - .quad sys32_fallocate - .quad compat_sys_timerfd_settime /* 325 */ - .quad compat_sys_timerfd_gettime - .quad compat_sys_signalfd4 - .quad sys_eventfd2 - .quad sys_epoll_create1 - .quad sys_dup3 /* 330 */ - .quad sys_pipe2 - .quad sys_inotify_init1 - .quad compat_sys_preadv - .quad compat_sys_pwritev - .quad compat_sys_rt_tgsigqueueinfo /* 335 */ - .quad sys_perf_event_open - .quad compat_sys_recvmmsg - .quad sys_fanotify_init - .quad sys32_fanotify_mark - .quad sys_prlimit64 /* 340 */ - .quad sys_name_to_handle_at - .quad compat_sys_open_by_handle_at - .quad compat_sys_clock_adjtime - .quad sys_syncfs - .quad compat_sys_sendmmsg /* 345 */ - .quad sys_setns - .quad compat_sys_process_vm_readv - .quad compat_sys_process_vm_writev -ia32_syscall_end: diff --git a/arch/x86/ia32/syscall_ia32.c b/arch/x86/ia32/syscall_ia32.c new file mode 100644 index 0000000..d04d3db --- /dev/null +++ b/arch/x86/ia32/syscall_ia32.c @@ -0,0 +1,25 @@ +/* System call table for ia32 emulation. */ + +#include +#include +#include +#include + +#define __SYSCALL_I386(nr, sym, compat) extern asmlinkage void compat(void) ; +#include +#undef __SYSCALL_I386 + +#define __SYSCALL_I386(nr, sym, compat) [nr] = compat, + +typedef void (*sys_call_ptr_t)(void); + +extern void compat_ni_syscall(void); + +const sys_call_ptr_t ia32_sys_call_table[__NR_ia32_syscall_max+1] = { + /* + * Smells like a like a compiler bug -- it doesn't work + * when the & below is removed. + */ + [0 ... __NR_ia32_syscall_max] = &compat_ni_syscall, +#include +}; diff --git a/arch/x86/include/asm/Kbuild b/arch/x86/include/asm/Kbuild index 6fa90a8..b57e6a4 100644 --- a/arch/x86/include/asm/Kbuild +++ b/arch/x86/include/asm/Kbuild @@ -19,7 +19,8 @@ header-y += processor-flags.h header-y += ptrace-abi.h header-y += sigcontext32.h header-y += ucontext.h -header-y += unistd_32.h -header-y += unistd_64.h header-y += vm86.h header-y += vsyscall.h + +genhdr-y += unistd_32.h +genhdr-y += unistd_64.h diff --git a/arch/x86/include/asm/ia32_unistd.h b/arch/x86/include/asm/ia32_unistd.h index 976f6ec..b0d5716 100644 --- a/arch/x86/include/asm/ia32_unistd.h +++ b/arch/x86/include/asm/ia32_unistd.h @@ -2,17 +2,10 @@ #define _ASM_X86_IA32_UNISTD_H /* - * This file contains the system call numbers of the ia32 port, + * This file contains the system call numbers of the ia32 compat ABI, * this is for the kernel only. - * Only add syscalls here where some part of the kernel needs to know - * the number. This should be otherwise in sync with asm-x86/unistd_32.h. -AK */ - -#define __NR_ia32_restart_syscall 0 -#define __NR_ia32_exit 1 -#define __NR_ia32_read 3 -#define __NR_ia32_write 4 -#define __NR_ia32_sigreturn 119 -#define __NR_ia32_rt_sigreturn 173 +#define __SYSCALL_ia32_NR(x) (x) +#include #endif /* _ASM_X86_IA32_UNISTD_H */ diff --git a/arch/x86/include/asm/unistd.h b/arch/x86/include/asm/unistd.h index 2a58ed3..b4a3db7 100644 --- a/arch/x86/include/asm/unistd.h +++ b/arch/x86/include/asm/unistd.h @@ -1,13 +1,59 @@ +#ifndef _ASM_X86_UNISTD_H +#define _ASM_X86_UNISTD_H 1 + #ifdef __KERNEL__ # ifdef CONFIG_X86_32 -# include "unistd_32.h" + +# include +# define __ARCH_WANT_IPC_PARSE_VERSION +# define __ARCH_WANT_STAT64 +# define __ARCH_WANT_SYS_OLD_MMAP +# define __ARCH_WANT_SYS_OLD_SELECT + # else -# include "unistd_64.h" + +# include +# define __ARCH_WANT_COMPAT_SYS_TIME + # endif + +# define __ARCH_WANT_OLD_READDIR +# define __ARCH_WANT_OLD_STAT +# define __ARCH_WANT_SYS_ALARM +# define __ARCH_WANT_SYS_FADVISE64 +# define __ARCH_WANT_SYS_GETHOSTNAME +# define __ARCH_WANT_SYS_GETPGRP +# define __ARCH_WANT_SYS_LLSEEK +# define __ARCH_WANT_SYS_NICE +# define __ARCH_WANT_SYS_OLDUMOUNT +# define __ARCH_WANT_SYS_OLD_GETRLIMIT +# define __ARCH_WANT_SYS_OLD_UNAME +# define __ARCH_WANT_SYS_PAUSE +# define __ARCH_WANT_SYS_RT_SIGACTION +# define __ARCH_WANT_SYS_RT_SIGSUSPEND +# define __ARCH_WANT_SYS_SGETMASK +# define __ARCH_WANT_SYS_SIGNAL +# define __ARCH_WANT_SYS_SIGPENDING +# define __ARCH_WANT_SYS_SIGPROCMASK +# define __ARCH_WANT_SYS_SOCKETCALL +# define __ARCH_WANT_SYS_TIME +# define __ARCH_WANT_SYS_UTIME +# define __ARCH_WANT_SYS_WAITPID + +/* + * "Conditional" syscalls + * + * What we want is __attribute__((weak,alias("sys_ni_syscall"))), + * but it doesn't work on all toolchains, so we just do it by hand + */ +# define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall") + #else # ifdef __i386__ -# include "unistd_32.h" +# include # else -# include "unistd_64.h" +# include # endif #endif + +#endif /* _ASM_X86_UNISTD_H */ diff --git a/arch/x86/include/asm/unistd_32.h b/arch/x86/include/asm/unistd_32.h deleted file mode 100644 index 599c77d..0000000 --- a/arch/x86/include/asm/unistd_32.h +++ /dev/null @@ -1,401 +0,0 @@ -#ifndef _ASM_X86_UNISTD_32_H -#define _ASM_X86_UNISTD_32_H - -/* - * This file contains the system call numbers. - */ - -#define __NR_restart_syscall 0 -#define __NR_exit 1 -#define __NR_fork 2 -#define __NR_read 3 -#define __NR_write 4 -#define __NR_open 5 -#define __NR_close 6 -#define __NR_waitpid 7 -#define __NR_creat 8 -#define __NR_link 9 -#define __NR_unlink 10 -#define __NR_execve 11 -#define __NR_chdir 12 -#define __NR_time 13 -#define __NR_mknod 14 -#define __NR_chmod 15 -#define __NR_lchown 16 -#define __NR_break 17 -#define __NR_oldstat 18 -#define __NR_lseek 19 -#define __NR_getpid 20 -#define __NR_mount 21 -#define __NR_umount 22 -#define __NR_setuid 23 -#define __NR_getuid 24 -#define __NR_stime 25 -#define __NR_ptrace 26 -#define __NR_alarm 27 -#define __NR_oldfstat 28 -#define __NR_pause 29 -#define __NR_utime 30 -#define __NR_stty 31 -#define __NR_gtty 32 -#define __NR_access 33 -#define __NR_nice 34 -#define __NR_ftime 35 -#define __NR_sync 36 -#define __NR_kill 37 -#define __NR_rename 38 -#define __NR_mkdir 39 -#define __NR_rmdir 40 -#define __NR_dup 41 -#define __NR_pipe 42 -#define __NR_times 43 -#define __NR_prof 44 -#define __NR_brk 45 -#define __NR_setgid 46 -#define __NR_getgid 47 -#define __NR_signal 48 -#define __NR_geteuid 49 -#define __NR_getegid 50 -#define __NR_acct 51 -#define __NR_umount2 52 -#define __NR_lock 53 -#define __NR_ioctl 54 -#define __NR_fcntl 55 -#define __NR_mpx 56 -#define __NR_setpgid 57 -#define __NR_ulimit 58 -#define __NR_oldolduname 59 -#define __NR_umask 60 -#define __NR_chroot 61 -#define __NR_ustat 62 -#define __NR_dup2 63 -#define __NR_getppid 64 -#define __NR_getpgrp 65 -#define __NR_setsid 66 -#define __NR_sigaction 67 -#define __NR_sgetmask 68 -#define __NR_ssetmask 69 -#define __NR_setreuid 70 -#define __NR_setregid 71 -#define __NR_sigsuspend 72 -#define __NR_sigpending 73 -#define __NR_sethostname 74 -#define __NR_setrlimit 75 -#define __NR_getrlimit 76 /* Back compatible 2Gig limited rlimit */ -#define __NR_getrusage 77 -#define __NR_gettimeofday 78 -#define __NR_settimeofday 79 -#define __NR_getgroups 80 -#define __NR_setgroups 81 -#define __NR_select 82 -#define __NR_symlink 83 -#define __NR_oldlstat 84 -#define __NR_readlink 85 -#define __NR_uselib 86 -#define __NR_swapon 87 -#define __NR_reboot 88 -#define __NR_readdir 89 -#define __NR_mmap 90 -#define __NR_munmap 91 -#define __NR_truncate 92 -#define __NR_ftruncate 93 -#define __NR_fchmod 94 -#define __NR_fchown 95 -#define __NR_getpriority 96 -#define __NR_setpriority 97 -#define __NR_profil 98 -#define __NR_statfs 99 -#define __NR_fstatfs 100 -#define __NR_ioperm 101 -#define __NR_socketcall 102 -#define __NR_syslog 103 -#define __NR_setitimer 104 -#define __NR_getitimer 105 -#define __NR_stat 106 -#define __NR_lstat 107 -#define __NR_fstat 108 -#define __NR_olduname 109 -#define __NR_iopl 110 -#define __NR_vhangup 111 -#define __NR_idle 112 -#define __NR_vm86old 113 -#define __NR_wait4 114 -#define __NR_swapoff 115 -#define __NR_sysinfo 116 -#define __NR_ipc 117 -#define __NR_fsync 118 -#define __NR_sigreturn 119 -#define __NR_clone 120 -#define __NR_setdomainname 121 -#define __NR_uname 122 -#define __NR_modify_ldt 123 -#define __NR_adjtimex 124 -#define __NR_mprotect 125 -#define __NR_sigprocmask 126 -#define __NR_create_module 127 -#define __NR_init_module 128 -#define __NR_delete_module 129 -#define __NR_get_kernel_syms 130 -#define __NR_quotactl 131 -#define __NR_getpgid 132 -#define __NR_fchdir 133 -#define __NR_bdflush 134 -#define __NR_sysfs 135 -#define __NR_personality 136 -#define __NR_afs_syscall 137 /* Syscall for Andrew File System */ -#define __NR_setfsuid 138 -#define __NR_setfsgid 139 -#define __NR__llseek 140 -#define __NR_getdents 141 -#define __NR__newselect 142 -#define __NR_flock 143 -#define __NR_msync 144 -#define __NR_readv 145 -#define __NR_writev 146 -#define __NR_getsid 147 -#define __NR_fdatasync 148 -#define __NR__sysctl 149 -#define __NR_mlock 150 -#define __NR_munlock 151 -#define __NR_mlockall 152 -#define __NR_munlockall 153 -#define __NR_sched_setparam 154 -#define __NR_sched_getparam 155 -#define __NR_sched_setscheduler 156 -#define __NR_sched_getscheduler 157 -#define __NR_sched_yield 158 -#define __NR_sched_get_priority_max 159 -#define __NR_sched_get_priority_min 160 -#define __NR_sched_rr_get_interval 161 -#define __NR_nanosleep 162 -#define __NR_mremap 163 -#define __NR_setresuid 164 -#define __NR_getresuid 165 -#define __NR_vm86 166 -#define __NR_query_module 167 -#define __NR_poll 168 -#define __NR_nfsservctl 169 -#define __NR_setresgid 170 -#define __NR_getresgid 171 -#define __NR_prctl 172 -#define __NR_rt_sigreturn 173 -#define __NR_rt_sigaction 174 -#define __NR_rt_sigprocmask 175 -#define __NR_rt_sigpending 176 -#define __NR_rt_sigtimedwait 177 -#define __NR_rt_sigqueueinfo 178 -#define __NR_rt_sigsuspend 179 -#define __NR_pread64 180 -#define __NR_pwrite64 181 -#define __NR_chown 182 -#define __NR_getcwd 183 -#define __NR_capget 184 -#define __NR_capset 185 -#define __NR_sigaltstack 186 -#define __NR_sendfile 187 -#define __NR_getpmsg 188 /* some people actually want streams */ -#define __NR_putpmsg 189 /* some people actually want streams */ -#define __NR_vfork 190 -#define __NR_ugetrlimit 191 /* SuS compliant getrlimit */ -#define __NR_mmap2 192 -#define __NR_truncate64 193 -#define __NR_ftruncate64 194 -#define __NR_stat64 195 -#define __NR_lstat64 196 -#define __NR_fstat64 197 -#define __NR_lchown32 198 -#define __NR_getuid32 199 -#define __NR_getgid32 200 -#define __NR_geteuid32 201 -#define __NR_getegid32 202 -#define __NR_setreuid32 203 -#define __NR_setregid32 204 -#define __NR_getgroups32 205 -#define __NR_setgroups32 206 -#define __NR_fchown32 207 -#define __NR_setresuid32 208 -#define __NR_getresuid32 209 -#define __NR_setresgid32 210 -#define __NR_getresgid32 211 -#define __NR_chown32 212 -#define __NR_setuid32 213 -#define __NR_setgid32 214 -#define __NR_setfsuid32 215 -#define __NR_setfsgid32 216 -#define __NR_pivot_root 217 -#define __NR_mincore 218 -#define __NR_madvise 219 -#define __NR_madvise1 219 /* delete when C lib stub is removed */ -#define __NR_getdents64 220 -#define __NR_fcntl64 221 -/* 223 is unused */ -#define __NR_gettid 224 -#define __NR_readahead 225 -#define __NR_setxattr 226 -#define __NR_lsetxattr 227 -#define __NR_fsetxattr 228 -#define __NR_getxattr 229 -#define __NR_lgetxattr 230 -#define __NR_fgetxattr 231 -#define __NR_listxattr 232 -#define __NR_llistxattr 233 -#define __NR_flistxattr 234 -#define __NR_removexattr 235 -#define __NR_lremovexattr 236 -#define __NR_fremovexattr 237 -#define __NR_tkill 238 -#define __NR_sendfile64 239 -#define __NR_futex 240 -#define __NR_sched_setaffinity 241 -#define __NR_sched_getaffinity 242 -#define __NR_set_thread_area 243 -#define __NR_get_thread_area 244 -#define __NR_io_setup 245 -#define __NR_io_destroy 246 -#define __NR_io_getevents 247 -#define __NR_io_submit 248 -#define __NR_io_cancel 249 -#define __NR_fadvise64 250 -/* 251 is available for reuse (was briefly sys_set_zone_reclaim) */ -#define __NR_exit_group 252 -#define __NR_lookup_dcookie 253 -#define __NR_epoll_create 254 -#define __NR_epoll_ctl 255 -#define __NR_epoll_wait 256 -#define __NR_remap_file_pages 257 -#define __NR_set_tid_address 258 -#define __NR_timer_create 259 -#define __NR_timer_settime (__NR_timer_create+1) -#define __NR_timer_gettime (__NR_timer_create+2) -#define __NR_timer_getoverrun (__NR_timer_create+3) -#define __NR_timer_delete (__NR_timer_create+4) -#define __NR_clock_settime (__NR_timer_create+5) -#define __NR_clock_gettime (__NR_timer_create+6) -#define __NR_clock_getres (__NR_timer_create+7) -#define __NR_clock_nanosleep (__NR_timer_create+8) -#define __NR_statfs64 268 -#define __NR_fstatfs64 269 -#define __NR_tgkill 270 -#define __NR_utimes 271 -#define __NR_fadvise64_64 272 -#define __NR_vserver 273 -#define __NR_mbind 274 -#define __NR_get_mempolicy 275 -#define __NR_set_mempolicy 276 -#define __NR_mq_open 277 -#define __NR_mq_unlink (__NR_mq_open+1) -#define __NR_mq_timedsend (__NR_mq_open+2) -#define __NR_mq_timedreceive (__NR_mq_open+3) -#define __NR_mq_notify (__NR_mq_open+4) -#define __NR_mq_getsetattr (__NR_mq_open+5) -#define __NR_kexec_load 283 -#define __NR_waitid 284 -/* #define __NR_sys_setaltroot 285 */ -#define __NR_add_key 286 -#define __NR_request_key 287 -#define __NR_keyctl 288 -#define __NR_ioprio_set 289 -#define __NR_ioprio_get 290 -#define __NR_inotify_init 291 -#define __NR_inotify_add_watch 292 -#define __NR_inotify_rm_watch 293 -#define __NR_migrate_pages 294 -#define __NR_openat 295 -#define __NR_mkdirat 296 -#define __NR_mknodat 297 -#define __NR_fchownat 298 -#define __NR_futimesat 299 -#define __NR_fstatat64 300 -#define __NR_unlinkat 301 -#define __NR_renameat 302 -#define __NR_linkat 303 -#define __NR_symlinkat 304 -#define __NR_readlinkat 305 -#define __NR_fchmodat 306 -#define __NR_faccessat 307 -#define __NR_pselect6 308 -#define __NR_ppoll 309 -#define __NR_unshare 310 -#define __NR_set_robust_list 311 -#define __NR_get_robust_list 312 -#define __NR_splice 313 -#define __NR_sync_file_range 314 -#define __NR_tee 315 -#define __NR_vmsplice 316 -#define __NR_move_pages 317 -#define __NR_getcpu 318 -#define __NR_epoll_pwait 319 -#define __NR_utimensat 320 -#define __NR_signalfd 321 -#define __NR_timerfd_create 322 -#define __NR_eventfd 323 -#define __NR_fallocate 324 -#define __NR_timerfd_settime 325 -#define __NR_timerfd_gettime 326 -#define __NR_signalfd4 327 -#define __NR_eventfd2 328 -#define __NR_epoll_create1 329 -#define __NR_dup3 330 -#define __NR_pipe2 331 -#define __NR_inotify_init1 332 -#define __NR_preadv 333 -#define __NR_pwritev 334 -#define __NR_rt_tgsigqueueinfo 335 -#define __NR_perf_event_open 336 -#define __NR_recvmmsg 337 -#define __NR_fanotify_init 338 -#define __NR_fanotify_mark 339 -#define __NR_prlimit64 340 -#define __NR_name_to_handle_at 341 -#define __NR_open_by_handle_at 342 -#define __NR_clock_adjtime 343 -#define __NR_syncfs 344 -#define __NR_sendmmsg 345 -#define __NR_setns 346 -#define __NR_process_vm_readv 347 -#define __NR_process_vm_writev 348 - -#ifdef __KERNEL__ - -#define NR_syscalls 349 - -#define __ARCH_WANT_IPC_PARSE_VERSION -#define __ARCH_WANT_OLD_READDIR -#define __ARCH_WANT_OLD_STAT -#define __ARCH_WANT_STAT64 -#define __ARCH_WANT_SYS_ALARM -#define __ARCH_WANT_SYS_GETHOSTNAME -#define __ARCH_WANT_SYS_IPC -#define __ARCH_WANT_SYS_PAUSE -#define __ARCH_WANT_SYS_SGETMASK -#define __ARCH_WANT_SYS_SIGNAL -#define __ARCH_WANT_SYS_TIME -#define __ARCH_WANT_SYS_UTIME -#define __ARCH_WANT_SYS_WAITPID -#define __ARCH_WANT_SYS_SOCKETCALL -#define __ARCH_WANT_SYS_FADVISE64 -#define __ARCH_WANT_SYS_GETPGRP -#define __ARCH_WANT_SYS_LLSEEK -#define __ARCH_WANT_SYS_NICE -#define __ARCH_WANT_SYS_OLD_GETRLIMIT -#define __ARCH_WANT_SYS_OLD_UNAME -#define __ARCH_WANT_SYS_OLD_MMAP -#define __ARCH_WANT_SYS_OLD_SELECT -#define __ARCH_WANT_SYS_OLDUMOUNT -#define __ARCH_WANT_SYS_SIGPENDING -#define __ARCH_WANT_SYS_SIGPROCMASK -#define __ARCH_WANT_SYS_RT_SIGACTION -#define __ARCH_WANT_SYS_RT_SIGSUSPEND - -/* - * "Conditional" syscalls - * - * What we want is __attribute__((weak,alias("sys_ni_syscall"))), - * but it doesn't work on all toolchains, so we just do it by hand - */ -#ifndef cond_syscall -#define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall") -#endif - -#endif /* __KERNEL__ */ -#endif /* _ASM_X86_UNISTD_32_H */ diff --git a/arch/x86/include/asm/unistd_64.h b/arch/x86/include/asm/unistd_64.h deleted file mode 100644 index 0431f19..0000000 --- a/arch/x86/include/asm/unistd_64.h +++ /dev/null @@ -1,732 +0,0 @@ -#ifndef _ASM_X86_UNISTD_64_H -#define _ASM_X86_UNISTD_64_H - -#ifndef __SYSCALL -#define __SYSCALL(a, b) -#endif - -/* - * This file contains the system call numbers. - * - * Note: holes are not allowed. - */ - -/* at least 8 syscall per cacheline */ -#define __NR_read 0 -__SYSCALL(__NR_read, sys_read) -#define __NR_write 1 -__SYSCALL(__NR_write, sys_write) -#define __NR_open 2 -__SYSCALL(__NR_open, sys_open) -#define __NR_close 3 -__SYSCALL(__NR_close, sys_close) -#define __NR_stat 4 -__SYSCALL(__NR_stat, sys_newstat) -#define __NR_fstat 5 -__SYSCALL(__NR_fstat, sys_newfstat) -#define __NR_lstat 6 -__SYSCALL(__NR_lstat, sys_newlstat) -#define __NR_poll 7 -__SYSCALL(__NR_poll, sys_poll) - -#define __NR_lseek 8 -__SYSCALL(__NR_lseek, sys_lseek) -#define __NR_mmap 9 -__SYSCALL(__NR_mmap, sys_mmap) -#define __NR_mprotect 10 -__SYSCALL(__NR_mprotect, sys_mprotect) -#define __NR_munmap 11 -__SYSCALL(__NR_munmap, sys_munmap) -#define __NR_brk 12 -__SYSCALL(__NR_brk, sys_brk) -#define __NR_rt_sigaction 13 -__SYSCALL(__NR_rt_sigaction, sys_rt_sigaction) -#define __NR_rt_sigprocmask 14 -__SYSCALL(__NR_rt_sigprocmask, sys_rt_sigprocmask) -#define __NR_rt_sigreturn 15 -__SYSCALL(__NR_rt_sigreturn, stub_rt_sigreturn) - -#define __NR_ioctl 16 -__SYSCALL(__NR_ioctl, sys_ioctl) -#define __NR_pread64 17 -__SYSCALL(__NR_pread64, sys_pread64) -#define __NR_pwrite64 18 -__SYSCALL(__NR_pwrite64, sys_pwrite64) -#define __NR_readv 19 -__SYSCALL(__NR_readv, sys_readv) -#define __NR_writev 20 -__SYSCALL(__NR_writev, sys_writev) -#define __NR_access 21 -__SYSCALL(__NR_access, sys_access) -#define __NR_pipe 22 -__SYSCALL(__NR_pipe, sys_pipe) -#define __NR_select 23 -__SYSCALL(__NR_select, sys_select) - -#define __NR_sched_yield 24 -__SYSCALL(__NR_sched_yield, sys_sched_yield) -#define __NR_mremap 25 -__SYSCALL(__NR_mremap, sys_mremap) -#define __NR_msync 26 -__SYSCALL(__NR_msync, sys_msync) -#define __NR_mincore 27 -__SYSCALL(__NR_mincore, sys_mincore) -#define __NR_madvise 28 -__SYSCALL(__NR_madvise, sys_madvise) -#define __NR_shmget 29 -__SYSCALL(__NR_shmget, sys_shmget) -#define __NR_shmat 30 -__SYSCALL(__NR_shmat, sys_shmat) -#define __NR_shmctl 31 -__SYSCALL(__NR_shmctl, sys_shmctl) - -#define __NR_dup 32 -__SYSCALL(__NR_dup, sys_dup) -#define __NR_dup2 33 -__SYSCALL(__NR_dup2, sys_dup2) -#define __NR_pause 34 -__SYSCALL(__NR_pause, sys_pause) -#define __NR_nanosleep 35 -__SYSCALL(__NR_nanosleep, sys_nanosleep) -#define __NR_getitimer 36 -__SYSCALL(__NR_getitimer, sys_getitimer) -#define __NR_alarm 37 -__SYSCALL(__NR_alarm, sys_alarm) -#define __NR_setitimer 38 -__SYSCALL(__NR_setitimer, sys_setitimer) -#define __NR_getpid 39 -__SYSCALL(__NR_getpid, sys_getpid) - -#define __NR_sendfile 40 -__SYSCALL(__NR_sendfile, sys_sendfile64) -#define __NR_socket 41 -__SYSCALL(__NR_socket, sys_socket) -#define __NR_connect 42 -__SYSCALL(__NR_connect, sys_connect) -#define __NR_accept 43 -__SYSCALL(__NR_accept, sys_accept) -#define __NR_sendto 44 -__SYSCALL(__NR_sendto, sys_sendto) -#define __NR_recvfrom 45 -__SYSCALL(__NR_recvfrom, sys_recvfrom) -#define __NR_sendmsg 46 -__SYSCALL(__NR_sendmsg, sys_sendmsg) -#define __NR_recvmsg 47 -__SYSCALL(__NR_recvmsg, sys_recvmsg) - -#define __NR_shutdown 48 -__SYSCALL(__NR_shutdown, sys_shutdown) -#define __NR_bind 49 -__SYSCALL(__NR_bind, sys_bind) -#define __NR_listen 50 -__SYSCALL(__NR_listen, sys_listen) -#define __NR_getsockname 51 -__SYSCALL(__NR_getsockname, sys_getsockname) -#define __NR_getpeername 52 -__SYSCALL(__NR_getpeername, sys_getpeername) -#define __NR_socketpair 53 -__SYSCALL(__NR_socketpair, sys_socketpair) -#define __NR_setsockopt 54 -__SYSCALL(__NR_setsockopt, sys_setsockopt) -#define __NR_getsockopt 55 -__SYSCALL(__NR_getsockopt, sys_getsockopt) - -#define __NR_clone 56 -__SYSCALL(__NR_clone, stub_clone) -#define __NR_fork 57 -__SYSCALL(__NR_fork, stub_fork) -#define __NR_vfork 58 -__SYSCALL(__NR_vfork, stub_vfork) -#define __NR_execve 59 -__SYSCALL(__NR_execve, stub_execve) -#define __NR_exit 60 -__SYSCALL(__NR_exit, sys_exit) -#define __NR_wait4 61 -__SYSCALL(__NR_wait4, sys_wait4) -#define __NR_kill 62 -__SYSCALL(__NR_kill, sys_kill) -#define __NR_uname 63 -__SYSCALL(__NR_uname, sys_newuname) - -#define __NR_semget 64 -__SYSCALL(__NR_semget, sys_semget) -#define __NR_semop 65 -__SYSCALL(__NR_semop, sys_semop) -#define __NR_semctl 66 -__SYSCALL(__NR_semctl, sys_semctl) -#define __NR_shmdt 67 -__SYSCALL(__NR_shmdt, sys_shmdt) -#define __NR_msgget 68 -__SYSCALL(__NR_msgget, sys_msgget) -#define __NR_msgsnd 69 -__SYSCALL(__NR_msgsnd, sys_msgsnd) -#define __NR_msgrcv 70 -__SYSCALL(__NR_msgrcv, sys_msgrcv) -#define __NR_msgctl 71 -__SYSCALL(__NR_msgctl, sys_msgctl) - -#define __NR_fcntl 72 -__SYSCALL(__NR_fcntl, sys_fcntl) -#define __NR_flock 73 -__SYSCALL(__NR_flock, sys_flock) -#define __NR_fsync 74 -__SYSCALL(__NR_fsync, sys_fsync) -#define __NR_fdatasync 75 -__SYSCALL(__NR_fdatasync, sys_fdatasync) -#define __NR_truncate 76 -__SYSCALL(__NR_truncate, sys_truncate) -#define __NR_ftruncate 77 -__SYSCALL(__NR_ftruncate, sys_ftruncate) -#define __NR_getdents 78 -__SYSCALL(__NR_getdents, sys_getdents) -#define __NR_getcwd 79 -__SYSCALL(__NR_getcwd, sys_getcwd) - -#define __NR_chdir 80 -__SYSCALL(__NR_chdir, sys_chdir) -#define __NR_fchdir 81 -__SYSCALL(__NR_fchdir, sys_fchdir) -#define __NR_rename 82 -__SYSCALL(__NR_rename, sys_rename) -#define __NR_mkdir 83 -__SYSCALL(__NR_mkdir, sys_mkdir) -#define __NR_rmdir 84 -__SYSCALL(__NR_rmdir, sys_rmdir) -#define __NR_creat 85 -__SYSCALL(__NR_creat, sys_creat) -#define __NR_link 86 -__SYSCALL(__NR_link, sys_link) -#define __NR_unlink 87 -__SYSCALL(__NR_unlink, sys_unlink) - -#define __NR_symlink 88 -__SYSCALL(__NR_symlink, sys_symlink) -#define __NR_readlink 89 -__SYSCALL(__NR_readlink, sys_readlink) -#define __NR_chmod 90 -__SYSCALL(__NR_chmod, sys_chmod) -#define __NR_fchmod 91 -__SYSCALL(__NR_fchmod, sys_fchmod) -#define __NR_chown 92 -__SYSCALL(__NR_chown, sys_chown) -#define __NR_fchown 93 -__SYSCALL(__NR_fchown, sys_fchown) -#define __NR_lchown 94 -__SYSCALL(__NR_lchown, sys_lchown) -#define __NR_umask 95 -__SYSCALL(__NR_umask, sys_umask) - -#define __NR_gettimeofday 96 -__SYSCALL(__NR_gettimeofday, sys_gettimeofday) -#define __NR_getrlimit 97 -__SYSCALL(__NR_getrlimit, sys_getrlimit) -#define __NR_getrusage 98 -__SYSCALL(__NR_getrusage, sys_getrusage) -#define __NR_sysinfo 99 -__SYSCALL(__NR_sysinfo, sys_sysinfo) -#define __NR_times 100 -__SYSCALL(__NR_times, sys_times) -#define __NR_ptrace 101 -__SYSCALL(__NR_ptrace, sys_ptrace) -#define __NR_getuid 102 -__SYSCALL(__NR_getuid, sys_getuid) -#define __NR_syslog 103 -__SYSCALL(__NR_syslog, sys_syslog) - -/* at the very end the stuff that never runs during the benchmarks */ -#define __NR_getgid 104 -__SYSCALL(__NR_getgid, sys_getgid) -#define __NR_setuid 105 -__SYSCALL(__NR_setuid, sys_setuid) -#define __NR_setgid 106 -__SYSCALL(__NR_setgid, sys_setgid) -#define __NR_geteuid 107 -__SYSCALL(__NR_geteuid, sys_geteuid) -#define __NR_getegid 108 -__SYSCALL(__NR_getegid, sys_getegid) -#define __NR_setpgid 109 -__SYSCALL(__NR_setpgid, sys_setpgid) -#define __NR_getppid 110 -__SYSCALL(__NR_getppid, sys_getppid) -#define __NR_getpgrp 111 -__SYSCALL(__NR_getpgrp, sys_getpgrp) - -#define __NR_setsid 112 -__SYSCALL(__NR_setsid, sys_setsid) -#define __NR_setreuid 113 -__SYSCALL(__NR_setreuid, sys_setreuid) -#define __NR_setregid 114 -__SYSCALL(__NR_setregid, sys_setregid) -#define __NR_getgroups 115 -__SYSCALL(__NR_getgroups, sys_getgroups) -#define __NR_setgroups 116 -__SYSCALL(__NR_setgroups, sys_setgroups) -#define __NR_setresuid 117 -__SYSCALL(__NR_setresuid, sys_setresuid) -#define __NR_getresuid 118 -__SYSCALL(__NR_getresuid, sys_getresuid) -#define __NR_setresgid 119 -__SYSCALL(__NR_setresgid, sys_setresgid) - -#define __NR_getresgid 120 -__SYSCALL(__NR_getresgid, sys_getresgid) -#define __NR_getpgid 121 -__SYSCALL(__NR_getpgid, sys_getpgid) -#define __NR_setfsuid 122 -__SYSCALL(__NR_setfsuid, sys_setfsuid) -#define __NR_setfsgid 123 -__SYSCALL(__NR_setfsgid, sys_setfsgid) -#define __NR_getsid 124 -__SYSCALL(__NR_getsid, sys_getsid) -#define __NR_capget 125 -__SYSCALL(__NR_capget, sys_capget) -#define __NR_capset 126 -__SYSCALL(__NR_capset, sys_capset) - -#define __NR_rt_sigpending 127 -__SYSCALL(__NR_rt_sigpending, sys_rt_sigpending) -#define __NR_rt_sigtimedwait 128 -__SYSCALL(__NR_rt_sigtimedwait, sys_rt_sigtimedwait) -#define __NR_rt_sigqueueinfo 129 -__SYSCALL(__NR_rt_sigqueueinfo, sys_rt_sigqueueinfo) -#define __NR_rt_sigsuspend 130 -__SYSCALL(__NR_rt_sigsuspend, sys_rt_sigsuspend) -#define __NR_sigaltstack 131 -__SYSCALL(__NR_sigaltstack, stub_sigaltstack) -#define __NR_utime 132 -__SYSCALL(__NR_utime, sys_utime) -#define __NR_mknod 133 -__SYSCALL(__NR_mknod, sys_mknod) - -/* Only needed for a.out */ -#define __NR_uselib 134 -__SYSCALL(__NR_uselib, sys_ni_syscall) -#define __NR_personality 135 -__SYSCALL(__NR_personality, sys_personality) - -#define __NR_ustat 136 -__SYSCALL(__NR_ustat, sys_ustat) -#define __NR_statfs 137 -__SYSCALL(__NR_statfs, sys_statfs) -#define __NR_fstatfs 138 -__SYSCALL(__NR_fstatfs, sys_fstatfs) -#define __NR_sysfs 139 -__SYSCALL(__NR_sysfs, sys_sysfs) - -#define __NR_getpriority 140 -__SYSCALL(__NR_getpriority, sys_getpriority) -#define __NR_setpriority 141 -__SYSCALL(__NR_setpriority, sys_setpriority) -#define __NR_sched_setparam 142 -__SYSCALL(__NR_sched_setparam, sys_sched_setparam) -#define __NR_sched_getparam 143 -__SYSCALL(__NR_sched_getparam, sys_sched_getparam) -#define __NR_sched_setscheduler 144 -__SYSCALL(__NR_sched_setscheduler, sys_sched_setscheduler) -#define __NR_sched_getscheduler 145 -__SYSCALL(__NR_sched_getscheduler, sys_sched_getscheduler) -#define __NR_sched_get_priority_max 146 -__SYSCALL(__NR_sched_get_priority_max, sys_sched_get_priority_max) -#define __NR_sched_get_priority_min 147 -__SYSCALL(__NR_sched_get_priority_min, sys_sched_get_priority_min) -#define __NR_sched_rr_get_interval 148 -__SYSCALL(__NR_sched_rr_get_interval, sys_sched_rr_get_interval) - -#define __NR_mlock 149 -__SYSCALL(__NR_mlock, sys_mlock) -#define __NR_munlock 150 -__SYSCALL(__NR_munlock, sys_munlock) -#define __NR_mlockall 151 -__SYSCALL(__NR_mlockall, sys_mlockall) -#define __NR_munlockall 152 -__SYSCALL(__NR_munlockall, sys_munlockall) - -#define __NR_vhangup 153 -__SYSCALL(__NR_vhangup, sys_vhangup) - -#define __NR_modify_ldt 154 -__SYSCALL(__NR_modify_ldt, sys_modify_ldt) - -#define __NR_pivot_root 155 -__SYSCALL(__NR_pivot_root, sys_pivot_root) - -#define __NR__sysctl 156 -__SYSCALL(__NR__sysctl, sys_sysctl) - -#define __NR_prctl 157 -__SYSCALL(__NR_prctl, sys_prctl) -#define __NR_arch_prctl 158 -__SYSCALL(__NR_arch_prctl, sys_arch_prctl) - -#define __NR_adjtimex 159 -__SYSCALL(__NR_adjtimex, sys_adjtimex) - -#define __NR_setrlimit 160 -__SYSCALL(__NR_setrlimit, sys_setrlimit) - -#define __NR_chroot 161 -__SYSCALL(__NR_chroot, sys_chroot) - -#define __NR_sync 162 -__SYSCALL(__NR_sync, sys_sync) - -#define __NR_acct 163 -__SYSCALL(__NR_acct, sys_acct) - -#define __NR_settimeofday 164 -__SYSCALL(__NR_settimeofday, sys_settimeofday) - -#define __NR_mount 165 -__SYSCALL(__NR_mount, sys_mount) -#define __NR_umount2 166 -__SYSCALL(__NR_umount2, sys_umount) - -#define __NR_swapon 167 -__SYSCALL(__NR_swapon, sys_swapon) -#define __NR_swapoff 168 -__SYSCALL(__NR_swapoff, sys_swapoff) - -#define __NR_reboot 169 -__SYSCALL(__NR_reboot, sys_reboot) - -#define __NR_sethostname 170 -__SYSCALL(__NR_sethostname, sys_sethostname) -#define __NR_setdomainname 171 -__SYSCALL(__NR_setdomainname, sys_setdomainname) - -#define __NR_iopl 172 -__SYSCALL(__NR_iopl, stub_iopl) -#define __NR_ioperm 173 -__SYSCALL(__NR_ioperm, sys_ioperm) - -#define __NR_create_module 174 -__SYSCALL(__NR_create_module, sys_ni_syscall) -#define __NR_init_module 175 -__SYSCALL(__NR_init_module, sys_init_module) -#define __NR_delete_module 176 -__SYSCALL(__NR_delete_module, sys_delete_module) -#define __NR_get_kernel_syms 177 -__SYSCALL(__NR_get_kernel_syms, sys_ni_syscall) -#define __NR_query_module 178 -__SYSCALL(__NR_query_module, sys_ni_syscall) - -#define __NR_quotactl 179 -__SYSCALL(__NR_quotactl, sys_quotactl) - -#define __NR_nfsservctl 180 -__SYSCALL(__NR_nfsservctl, sys_ni_syscall) - -/* reserved for LiS/STREAMS */ -#define __NR_getpmsg 181 -__SYSCALL(__NR_getpmsg, sys_ni_syscall) -#define __NR_putpmsg 182 -__SYSCALL(__NR_putpmsg, sys_ni_syscall) - -/* reserved for AFS */ -#define __NR_afs_syscall 183 -__SYSCALL(__NR_afs_syscall, sys_ni_syscall) - -/* reserved for tux */ -#define __NR_tuxcall 184 -__SYSCALL(__NR_tuxcall, sys_ni_syscall) - -#define __NR_security 185 -__SYSCALL(__NR_security, sys_ni_syscall) - -#define __NR_gettid 186 -__SYSCALL(__NR_gettid, sys_gettid) - -#define __NR_readahead 187 -__SYSCALL(__NR_readahead, sys_readahead) -#define __NR_setxattr 188 -__SYSCALL(__NR_setxattr, sys_setxattr) -#define __NR_lsetxattr 189 -__SYSCALL(__NR_lsetxattr, sys_lsetxattr) -#define __NR_fsetxattr 190 -__SYSCALL(__NR_fsetxattr, sys_fsetxattr) -#define __NR_getxattr 191 -__SYSCALL(__NR_getxattr, sys_getxattr) -#define __NR_lgetxattr 192 -__SYSCALL(__NR_lgetxattr, sys_lgetxattr) -#define __NR_fgetxattr 193 -__SYSCALL(__NR_fgetxattr, sys_fgetxattr) -#define __NR_listxattr 194 -__SYSCALL(__NR_listxattr, sys_listxattr) -#define __NR_llistxattr 195 -__SYSCALL(__NR_llistxattr, sys_llistxattr) -#define __NR_flistxattr 196 -__SYSCALL(__NR_flistxattr, sys_flistxattr) -#define __NR_removexattr 197 -__SYSCALL(__NR_removexattr, sys_removexattr) -#define __NR_lremovexattr 198 -__SYSCALL(__NR_lremovexattr, sys_lremovexattr) -#define __NR_fremovexattr 199 -__SYSCALL(__NR_fremovexattr, sys_fremovexattr) -#define __NR_tkill 200 -__SYSCALL(__NR_tkill, sys_tkill) -#define __NR_time 201 -__SYSCALL(__NR_time, sys_time) -#define __NR_futex 202 -__SYSCALL(__NR_futex, sys_futex) -#define __NR_sched_setaffinity 203 -__SYSCALL(__NR_sched_setaffinity, sys_sched_setaffinity) -#define __NR_sched_getaffinity 204 -__SYSCALL(__NR_sched_getaffinity, sys_sched_getaffinity) -#define __NR_set_thread_area 205 -__SYSCALL(__NR_set_thread_area, sys_ni_syscall) /* use arch_prctl */ -#define __NR_io_setup 206 -__SYSCALL(__NR_io_setup, sys_io_setup) -#define __NR_io_destroy 207 -__SYSCALL(__NR_io_destroy, sys_io_destroy) -#define __NR_io_getevents 208 -__SYSCALL(__NR_io_getevents, sys_io_getevents) -#define __NR_io_submit 209 -__SYSCALL(__NR_io_submit, sys_io_submit) -#define __NR_io_cancel 210 -__SYSCALL(__NR_io_cancel, sys_io_cancel) -#define __NR_get_thread_area 211 -__SYSCALL(__NR_get_thread_area, sys_ni_syscall) /* use arch_prctl */ -#define __NR_lookup_dcookie 212 -__SYSCALL(__NR_lookup_dcookie, sys_lookup_dcookie) -#define __NR_epoll_create 213 -__SYSCALL(__NR_epoll_create, sys_epoll_create) -#define __NR_epoll_ctl_old 214 -__SYSCALL(__NR_epoll_ctl_old, sys_ni_syscall) -#define __NR_epoll_wait_old 215 -__SYSCALL(__NR_epoll_wait_old, sys_ni_syscall) -#define __NR_remap_file_pages 216 -__SYSCALL(__NR_remap_file_pages, sys_remap_file_pages) -#define __NR_getdents64 217 -__SYSCALL(__NR_getdents64, sys_getdents64) -#define __NR_set_tid_address 218 -__SYSCALL(__NR_set_tid_address, sys_set_tid_address) -#define __NR_restart_syscall 219 -__SYSCALL(__NR_restart_syscall, sys_restart_syscall) -#define __NR_semtimedop 220 -__SYSCALL(__NR_semtimedop, sys_semtimedop) -#define __NR_fadvise64 221 -__SYSCALL(__NR_fadvise64, sys_fadvise64) -#define __NR_timer_create 222 -__SYSCALL(__NR_timer_create, sys_timer_create) -#define __NR_timer_settime 223 -__SYSCALL(__NR_timer_settime, sys_timer_settime) -#define __NR_timer_gettime 224 -__SYSCALL(__NR_timer_gettime, sys_timer_gettime) -#define __NR_timer_getoverrun 225 -__SYSCALL(__NR_timer_getoverrun, sys_timer_getoverrun) -#define __NR_timer_delete 226 -__SYSCALL(__NR_timer_delete, sys_timer_delete) -#define __NR_clock_settime 227 -__SYSCALL(__NR_clock_settime, sys_clock_settime) -#define __NR_clock_gettime 228 -__SYSCALL(__NR_clock_gettime, sys_clock_gettime) -#define __NR_clock_getres 229 -__SYSCALL(__NR_clock_getres, sys_clock_getres) -#define __NR_clock_nanosleep 230 -__SYSCALL(__NR_clock_nanosleep, sys_clock_nanosleep) -#define __NR_exit_group 231 -__SYSCALL(__NR_exit_group, sys_exit_group) -#define __NR_epoll_wait 232 -__SYSCALL(__NR_epoll_wait, sys_epoll_wait) -#define __NR_epoll_ctl 233 -__SYSCALL(__NR_epoll_ctl, sys_epoll_ctl) -#define __NR_tgkill 234 -__SYSCALL(__NR_tgkill, sys_tgkill) -#define __NR_utimes 235 -__SYSCALL(__NR_utimes, sys_utimes) -#define __NR_vserver 236 -__SYSCALL(__NR_vserver, sys_ni_syscall) -#define __NR_mbind 237 -__SYSCALL(__NR_mbind, sys_mbind) -#define __NR_set_mempolicy 238 -__SYSCALL(__NR_set_mempolicy, sys_set_mempolicy) -#define __NR_get_mempolicy 239 -__SYSCALL(__NR_get_mempolicy, sys_get_mempolicy) -#define __NR_mq_open 240 -__SYSCALL(__NR_mq_open, sys_mq_open) -#define __NR_mq_unlink 241 -__SYSCALL(__NR_mq_unlink, sys_mq_unlink) -#define __NR_mq_timedsend 242 -__SYSCALL(__NR_mq_timedsend, sys_mq_timedsend) -#define __NR_mq_timedreceive 243 -__SYSCALL(__NR_mq_timedreceive, sys_mq_timedreceive) -#define __NR_mq_notify 244 -__SYSCALL(__NR_mq_notify, sys_mq_notify) -#define __NR_mq_getsetattr 245 -__SYSCALL(__NR_mq_getsetattr, sys_mq_getsetattr) -#define __NR_kexec_load 246 -__SYSCALL(__NR_kexec_load, sys_kexec_load) -#define __NR_waitid 247 -__SYSCALL(__NR_waitid, sys_waitid) -#define __NR_add_key 248 -__SYSCALL(__NR_add_key, sys_add_key) -#define __NR_request_key 249 -__SYSCALL(__NR_request_key, sys_request_key) -#define __NR_keyctl 250 -__SYSCALL(__NR_keyctl, sys_keyctl) -#define __NR_ioprio_set 251 -__SYSCALL(__NR_ioprio_set, sys_ioprio_set) -#define __NR_ioprio_get 252 -__SYSCALL(__NR_ioprio_get, sys_ioprio_get) -#define __NR_inotify_init 253 -__SYSCALL(__NR_inotify_init, sys_inotify_init) -#define __NR_inotify_add_watch 254 -__SYSCALL(__NR_inotify_add_watch, sys_inotify_add_watch) -#define __NR_inotify_rm_watch 255 -__SYSCALL(__NR_inotify_rm_watch, sys_inotify_rm_watch) -#define __NR_migrate_pages 256 -__SYSCALL(__NR_migrate_pages, sys_migrate_pages) -#define __NR_openat 257 -__SYSCALL(__NR_openat, sys_openat) -#define __NR_mkdirat 258 -__SYSCALL(__NR_mkdirat, sys_mkdirat) -#define __NR_mknodat 259 -__SYSCALL(__NR_mknodat, sys_mknodat) -#define __NR_fchownat 260 -__SYSCALL(__NR_fchownat, sys_fchownat) -#define __NR_futimesat 261 -__SYSCALL(__NR_futimesat, sys_futimesat) -#define __NR_newfstatat 262 -__SYSCALL(__NR_newfstatat, sys_newfstatat) -#define __NR_unlinkat 263 -__SYSCALL(__NR_unlinkat, sys_unlinkat) -#define __NR_renameat 264 -__SYSCALL(__NR_renameat, sys_renameat) -#define __NR_linkat 265 -__SYSCALL(__NR_linkat, sys_linkat) -#define __NR_symlinkat 266 -__SYSCALL(__NR_symlinkat, sys_symlinkat) -#define __NR_readlinkat 267 -__SYSCALL(__NR_readlinkat, sys_readlinkat) -#define __NR_fchmodat 268 -__SYSCALL(__NR_fchmodat, sys_fchmodat) -#define __NR_faccessat 269 -__SYSCALL(__NR_faccessat, sys_faccessat) -#define __NR_pselect6 270 -__SYSCALL(__NR_pselect6, sys_pselect6) -#define __NR_ppoll 271 -__SYSCALL(__NR_ppoll, sys_ppoll) -#define __NR_unshare 272 -__SYSCALL(__NR_unshare, sys_unshare) -#define __NR_set_robust_list 273 -__SYSCALL(__NR_set_robust_list, sys_set_robust_list) -#define __NR_get_robust_list 274 -__SYSCALL(__NR_get_robust_list, sys_get_robust_list) -#define __NR_splice 275 -__SYSCALL(__NR_splice, sys_splice) -#define __NR_tee 276 -__SYSCALL(__NR_tee, sys_tee) -#define __NR_sync_file_range 277 -__SYSCALL(__NR_sync_file_range, sys_sync_file_range) -#define __NR_vmsplice 278 -__SYSCALL(__NR_vmsplice, sys_vmsplice) -#define __NR_move_pages 279 -__SYSCALL(__NR_move_pages, sys_move_pages) -#define __NR_utimensat 280 -__SYSCALL(__NR_utimensat, sys_utimensat) -#define __NR_epoll_pwait 281 -__SYSCALL(__NR_epoll_pwait, sys_epoll_pwait) -#define __NR_signalfd 282 -__SYSCALL(__NR_signalfd, sys_signalfd) -#define __NR_timerfd_create 283 -__SYSCALL(__NR_timerfd_create, sys_timerfd_create) -#define __NR_eventfd 284 -__SYSCALL(__NR_eventfd, sys_eventfd) -#define __NR_fallocate 285 -__SYSCALL(__NR_fallocate, sys_fallocate) -#define __NR_timerfd_settime 286 -__SYSCALL(__NR_timerfd_settime, sys_timerfd_settime) -#define __NR_timerfd_gettime 287 -__SYSCALL(__NR_timerfd_gettime, sys_timerfd_gettime) -#define __NR_accept4 288 -__SYSCALL(__NR_accept4, sys_accept4) -#define __NR_signalfd4 289 -__SYSCALL(__NR_signalfd4, sys_signalfd4) -#define __NR_eventfd2 290 -__SYSCALL(__NR_eventfd2, sys_eventfd2) -#define __NR_epoll_create1 291 -__SYSCALL(__NR_epoll_create1, sys_epoll_create1) -#define __NR_dup3 292 -__SYSCALL(__NR_dup3, sys_dup3) -#define __NR_pipe2 293 -__SYSCALL(__NR_pipe2, sys_pipe2) -#define __NR_inotify_init1 294 -__SYSCALL(__NR_inotify_init1, sys_inotify_init1) -#define __NR_preadv 295 -__SYSCALL(__NR_preadv, sys_preadv) -#define __NR_pwritev 296 -__SYSCALL(__NR_pwritev, sys_pwritev) -#define __NR_rt_tgsigqueueinfo 297 -__SYSCALL(__NR_rt_tgsigqueueinfo, sys_rt_tgsigqueueinfo) -#define __NR_perf_event_open 298 -__SYSCALL(__NR_perf_event_open, sys_perf_event_open) -#define __NR_recvmmsg 299 -__SYSCALL(__NR_recvmmsg, sys_recvmmsg) -#define __NR_fanotify_init 300 -__SYSCALL(__NR_fanotify_init, sys_fanotify_init) -#define __NR_fanotify_mark 301 -__SYSCALL(__NR_fanotify_mark, sys_fanotify_mark) -#define __NR_prlimit64 302 -__SYSCALL(__NR_prlimit64, sys_prlimit64) -#define __NR_name_to_handle_at 303 -__SYSCALL(__NR_name_to_handle_at, sys_name_to_handle_at) -#define __NR_open_by_handle_at 304 -__SYSCALL(__NR_open_by_handle_at, sys_open_by_handle_at) -#define __NR_clock_adjtime 305 -__SYSCALL(__NR_clock_adjtime, sys_clock_adjtime) -#define __NR_syncfs 306 -__SYSCALL(__NR_syncfs, sys_syncfs) -#define __NR_sendmmsg 307 -__SYSCALL(__NR_sendmmsg, sys_sendmmsg) -#define __NR_setns 308 -__SYSCALL(__NR_setns, sys_setns) -#define __NR_getcpu 309 -__SYSCALL(__NR_getcpu, sys_getcpu) -#define __NR_process_vm_readv 310 -__SYSCALL(__NR_process_vm_readv, sys_process_vm_readv) -#define __NR_process_vm_writev 311 -__SYSCALL(__NR_process_vm_writev, sys_process_vm_writev) - -#ifndef __NO_STUBS -#define __ARCH_WANT_OLD_READDIR -#define __ARCH_WANT_OLD_STAT -#define __ARCH_WANT_SYS_ALARM -#define __ARCH_WANT_SYS_GETHOSTNAME -#define __ARCH_WANT_SYS_PAUSE -#define __ARCH_WANT_SYS_SGETMASK -#define __ARCH_WANT_SYS_SIGNAL -#define __ARCH_WANT_SYS_UTIME -#define __ARCH_WANT_SYS_WAITPID -#define __ARCH_WANT_SYS_SOCKETCALL -#define __ARCH_WANT_SYS_FADVISE64 -#define __ARCH_WANT_SYS_GETPGRP -#define __ARCH_WANT_SYS_LLSEEK -#define __ARCH_WANT_SYS_NICE -#define __ARCH_WANT_SYS_OLD_GETRLIMIT -#define __ARCH_WANT_SYS_OLD_UNAME -#define __ARCH_WANT_SYS_OLDUMOUNT -#define __ARCH_WANT_SYS_SIGPENDING -#define __ARCH_WANT_SYS_SIGPROCMASK -#define __ARCH_WANT_SYS_RT_SIGACTION -#define __ARCH_WANT_SYS_RT_SIGSUSPEND -#define __ARCH_WANT_SYS_TIME -#define __ARCH_WANT_COMPAT_SYS_TIME -#endif /* __NO_STUBS */ - -#ifdef __KERNEL__ - -#ifndef COMPILE_OFFSETS -#include -#define NR_syscalls (__NR_syscall_max + 1) -#endif - -/* - * "Conditional" syscalls - * - * What we want is __attribute__((weak,alias("sys_ni_syscall"))), - * but it doesn't work on all toolchains, so we just do it by hand - */ -#define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall") -#endif /* __KERNEL__ */ - -#endif /* _ASM_X86_UNISTD_64_H */ diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile index 8baca3c..8c473d9 100644 --- a/arch/x86/kernel/Makefile +++ b/arch/x86/kernel/Makefile @@ -25,7 +25,8 @@ obj-$(CONFIG_IRQ_WORK) += irq_work.o obj-y += probe_roms.o obj-$(CONFIG_X86_32) += sys_i386_32.o i386_ksyms_32.o obj-$(CONFIG_X86_64) += sys_x86_64.o x8664_ksyms_64.o -obj-$(CONFIG_X86_64) += syscall_64.o vsyscall_64.o +obj-y += syscall_$(BITS).o +obj-$(CONFIG_X86_64) += vsyscall_64.o obj-$(CONFIG_X86_64) += vsyscall_emu_64.o obj-y += bootflag.o e820.o obj-y += pci-dma.o quirks.o topology.o kdebugfs.o diff --git a/arch/x86/kernel/asm-offsets_32.c b/arch/x86/kernel/asm-offsets_32.c index 395a10e..85d98ab 100644 --- a/arch/x86/kernel/asm-offsets_32.c +++ b/arch/x86/kernel/asm-offsets_32.c @@ -3,6 +3,11 @@ #include #include "../../../drivers/lguest/lg.h" +#define __SYSCALL_I386(nr, sym, compat) [nr] = 1, +static char syscalls[] = { +#include +}; + /* workaround for a warning with -Wmissing-prototypes */ void foo(void); @@ -76,4 +81,7 @@ void foo(void) OFFSET(LGUEST_PAGES_regs_errcode, lguest_pages, regs.errcode); OFFSET(LGUEST_PAGES_regs, lguest_pages, regs); #endif + BLANK(); + DEFINE(__NR_syscall_max, sizeof(syscalls) - 1); + DEFINE(NR_syscalls, sizeof(syscalls)); } diff --git a/arch/x86/kernel/asm-offsets_64.c b/arch/x86/kernel/asm-offsets_64.c index e72a119..834e897 100644 --- a/arch/x86/kernel/asm-offsets_64.c +++ b/arch/x86/kernel/asm-offsets_64.c @@ -1,11 +1,12 @@ #include -#define __NO_STUBS 1 -#undef __SYSCALL -#undef _ASM_X86_UNISTD_64_H -#define __SYSCALL(nr, sym) [nr] = 1, -static char syscalls[] = { -#include +#define __SYSCALL_64(nr, sym, compat) [nr] = 1, +static char syscalls_64[] = { +#include +}; +#define __SYSCALL_I386(nr, sym, compat) [nr] = 1, +static char syscalls_ia32[] = { +#include }; int main(void) @@ -72,7 +73,11 @@ int main(void) OFFSET(TSS_ist, tss_struct, x86_tss.ist); BLANK(); - DEFINE(__NR_syscall_max, sizeof(syscalls) - 1); + DEFINE(__NR_syscall_max, sizeof(syscalls_64) - 1); + DEFINE(NR_syscalls, sizeof(syscalls_64)); + + DEFINE(__NR_ia32_syscall_max, sizeof(syscalls_ia32) - 1); + DEFINE(IA32_NR_syscalls, sizeof(syscalls_ia32)); return 0; } diff --git a/arch/x86/kernel/entry_32.S b/arch/x86/kernel/entry_32.S index f3f6f53..1ffcda2 100644 --- a/arch/x86/kernel/entry_32.S +++ b/arch/x86/kernel/entry_32.S @@ -81,8 +81,6 @@ * enough to patch inline, increasing performance. */ -#define nr_syscalls ((syscall_table_size)/4) - #ifdef CONFIG_PREEMPT #define preempt_stop(clobbers) DISABLE_INTERRUPTS(clobbers); TRACE_IRQS_OFF #else @@ -423,7 +421,7 @@ sysenter_past_esp: testl $_TIF_WORK_SYSCALL_ENTRY,TI_flags(%ebp) jnz sysenter_audit sysenter_do_call: - cmpl $(nr_syscalls), %eax + cmpl $(NR_syscalls), %eax jae syscall_badsys call *sys_call_table(,%eax,4) movl %eax,PT_EAX(%esp) @@ -504,7 +502,7 @@ ENTRY(system_call) # system call tracing in operation / emulation testl $_TIF_WORK_SYSCALL_ENTRY,TI_flags(%ebp) jnz syscall_trace_entry - cmpl $(nr_syscalls), %eax + cmpl $(NR_syscalls), %eax jae syscall_badsys syscall_call: call *sys_call_table(,%eax,4) @@ -650,7 +648,7 @@ syscall_trace_entry: movl %esp, %eax call syscall_trace_enter /* What it returned is what we'll actually use. */ - cmpl $(nr_syscalls), %eax + cmpl $(NR_syscalls), %eax jnae syscall_call jmp syscall_exit END(syscall_trace_entry) @@ -690,29 +688,28 @@ END(syscall_badsys) * System calls that need a pt_regs pointer. */ #define PTREGSCALL0(name) \ - ALIGN; \ -ptregs_##name: \ +ENTRY(ptregs_##name) ; \ leal 4(%esp),%eax; \ - jmp sys_##name; + jmp sys_##name; \ +ENDPROC(ptregs_##name) #define PTREGSCALL1(name) \ - ALIGN; \ -ptregs_##name: \ +ENTRY(ptregs_##name) ; \ leal 4(%esp),%edx; \ movl (PT_EBX+4)(%esp),%eax; \ - jmp sys_##name; + jmp sys_##name; \ +ENDPROC(ptregs_##name) #define PTREGSCALL2(name) \ - ALIGN; \ -ptregs_##name: \ +ENTRY(ptregs_##name) ; \ leal 4(%esp),%ecx; \ movl (PT_ECX+4)(%esp),%edx; \ movl (PT_EBX+4)(%esp),%eax; \ - jmp sys_##name; + jmp sys_##name; \ +ENDPROC(ptregs_##name) #define PTREGSCALL3(name) \ - ALIGN; \ -ptregs_##name: \ +ENTRY(ptregs_##name) ; \ CFI_STARTPROC; \ leal 4(%esp),%eax; \ pushl_cfi %eax; \ @@ -737,8 +734,7 @@ PTREGSCALL2(vm86) PTREGSCALL1(vm86old) /* Clone is an oddball. The 4th arg is in %edi */ - ALIGN; -ptregs_clone: +ENTRY(ptregs_clone) CFI_STARTPROC leal 4(%esp),%eax pushl_cfi %eax @@ -1209,11 +1205,6 @@ return_to_handler: jmp *%ecx #endif -.section .rodata,"a" -#include "syscall_table_32.S" - -syscall_table_size=(.-sys_call_table) - /* * Some functions should be protected against kprobes */ diff --git a/arch/x86/kernel/syscall_32.c b/arch/x86/kernel/syscall_32.c new file mode 100644 index 0000000..b37a573 --- /dev/null +++ b/arch/x86/kernel/syscall_32.c @@ -0,0 +1,25 @@ +/* System call table for i386. */ + +#include +#include +#include +#include + +#define __SYSCALL_I386(nr, sym, compat) extern asmlinkage void sym(void) ; +#include +#undef __SYSCALL_I386 + +#define __SYSCALL_I386(nr, sym, compat) [nr] = sym, + +typedef asmlinkage void (*sys_call_ptr_t)(void); + +extern asmlinkage void sys_ni_syscall(void); + +const sys_call_ptr_t sys_call_table[__NR_syscall_max+1] = { + /* + * Smells like a like a compiler bug -- it doesn't work + * when the & below is removed. + */ + [0 ... __NR_syscall_max] = &sys_ni_syscall, +#include +}; diff --git a/arch/x86/kernel/syscall_64.c b/arch/x86/kernel/syscall_64.c index 0edfafa..7ac7943 100644 --- a/arch/x86/kernel/syscall_64.c +++ b/arch/x86/kernel/syscall_64.c @@ -5,15 +5,11 @@ #include #include -#define __NO_STUBS +#define __SYSCALL_64(nr, sym, compat) extern asmlinkage void sym(void) ; +#include +#undef __SYSCALL_64 -#define __SYSCALL(nr, sym) extern asmlinkage void sym(void) ; -#undef _ASM_X86_UNISTD_64_H -#include - -#undef __SYSCALL -#define __SYSCALL(nr, sym) [nr] = sym, -#undef _ASM_X86_UNISTD_64_H +#define __SYSCALL_64(nr, sym, compat) [nr] = sym, typedef void (*sys_call_ptr_t)(void); @@ -25,5 +21,5 @@ const sys_call_ptr_t sys_call_table[__NR_syscall_max+1] = { * when the & below is removed. */ [0 ... __NR_syscall_max] = &sys_ni_syscall, -#include +#include }; diff --git a/arch/x86/kernel/syscall_table_32.S b/arch/x86/kernel/syscall_table_32.S deleted file mode 100644 index 9a0e312..0000000 --- a/arch/x86/kernel/syscall_table_32.S +++ /dev/null @@ -1,350 +0,0 @@ -ENTRY(sys_call_table) - .long sys_restart_syscall /* 0 - old "setup()" system call, used for restarting */ - .long sys_exit - .long ptregs_fork - .long sys_read - .long sys_write - .long sys_open /* 5 */ - .long sys_close - .long sys_waitpid - .long sys_creat - .long sys_link - .long sys_unlink /* 10 */ - .long ptregs_execve - .long sys_chdir - .long sys_time - .long sys_mknod - .long sys_chmod /* 15 */ - .long sys_lchown16 - .long sys_ni_syscall /* old break syscall holder */ - .long sys_stat - .long sys_lseek - .long sys_getpid /* 20 */ - .long sys_mount - .long sys_oldumount - .long sys_setuid16 - .long sys_getuid16 - .long sys_stime /* 25 */ - .long sys_ptrace - .long sys_alarm - .long sys_fstat - .long sys_pause - .long sys_utime /* 30 */ - .long sys_ni_syscall /* old stty syscall holder */ - .long sys_ni_syscall /* old gtty syscall holder */ - .long sys_access - .long sys_nice - .long sys_ni_syscall /* 35 - old ftime syscall holder */ - .long sys_sync - .long sys_kill - .long sys_rename - .long sys_mkdir - .long sys_rmdir /* 40 */ - .long sys_dup - .long sys_pipe - .long sys_times - .long sys_ni_syscall /* old prof syscall holder */ - .long sys_brk /* 45 */ - .long sys_setgid16 - .long sys_getgid16 - .long sys_signal - .long sys_geteuid16 - .long sys_getegid16 /* 50 */ - .long sys_acct - .long sys_umount /* recycled never used phys() */ - .long sys_ni_syscall /* old lock syscall holder */ - .long sys_ioctl - .long sys_fcntl /* 55 */ - .long sys_ni_syscall /* old mpx syscall holder */ - .long sys_setpgid - .long sys_ni_syscall /* old ulimit syscall holder */ - .long sys_olduname - .long sys_umask /* 60 */ - .long sys_chroot - .long sys_ustat - .long sys_dup2 - .long sys_getppid - .long sys_getpgrp /* 65 */ - .long sys_setsid - .long sys_sigaction - .long sys_sgetmask - .long sys_ssetmask - .long sys_setreuid16 /* 70 */ - .long sys_setregid16 - .long sys_sigsuspend - .long sys_sigpending - .long sys_sethostname - .long sys_setrlimit /* 75 */ - .long sys_old_getrlimit - .long sys_getrusage - .long sys_gettimeofday - .long sys_settimeofday - .long sys_getgroups16 /* 80 */ - .long sys_setgroups16 - .long sys_old_select - .long sys_symlink - .long sys_lstat - .long sys_readlink /* 85 */ - .long sys_uselib - .long sys_swapon - .long sys_reboot - .long sys_old_readdir - .long sys_old_mmap /* 90 */ - .long sys_munmap - .long sys_truncate - .long sys_ftruncate - .long sys_fchmod - .long sys_fchown16 /* 95 */ - .long sys_getpriority - .long sys_setpriority - .long sys_ni_syscall /* old profil syscall holder */ - .long sys_statfs - .long sys_fstatfs /* 100 */ - .long sys_ioperm - .long sys_socketcall - .long sys_syslog - .long sys_setitimer - .long sys_getitimer /* 105 */ - .long sys_newstat - .long sys_newlstat - .long sys_newfstat - .long sys_uname - .long ptregs_iopl /* 110 */ - .long sys_vhangup - .long sys_ni_syscall /* old "idle" system call */ - .long ptregs_vm86old - .long sys_wait4 - .long sys_swapoff /* 115 */ - .long sys_sysinfo - .long sys_ipc - .long sys_fsync - .long ptregs_sigreturn - .long ptregs_clone /* 120 */ - .long sys_setdomainname - .long sys_newuname - .long sys_modify_ldt - .long sys_adjtimex - .long sys_mprotect /* 125 */ - .long sys_sigprocmask - .long sys_ni_syscall /* old "create_module" */ - .long sys_init_module - .long sys_delete_module - .long sys_ni_syscall /* 130: old "get_kernel_syms" */ - .long sys_quotactl - .long sys_getpgid - .long sys_fchdir - .long sys_bdflush - .long sys_sysfs /* 135 */ - .long sys_personality - .long sys_ni_syscall /* reserved for afs_syscall */ - .long sys_setfsuid16 - .long sys_setfsgid16 - .long sys_llseek /* 140 */ - .long sys_getdents - .long sys_select - .long sys_flock - .long sys_msync - .long sys_readv /* 145 */ - .long sys_writev - .long sys_getsid - .long sys_fdatasync - .long sys_sysctl - .long sys_mlock /* 150 */ - .long sys_munlock - .long sys_mlockall - .long sys_munlockall - .long sys_sched_setparam - .long sys_sched_getparam /* 155 */ - .long sys_sched_setscheduler - .long sys_sched_getscheduler - .long sys_sched_yield - .long sys_sched_get_priority_max - .long sys_sched_get_priority_min /* 160 */ - .long sys_sched_rr_get_interval - .long sys_nanosleep - .long sys_mremap - .long sys_setresuid16 - .long sys_getresuid16 /* 165 */ - .long ptregs_vm86 - .long sys_ni_syscall /* Old sys_query_module */ - .long sys_poll - .long sys_ni_syscall /* Old nfsservctl */ - .long sys_setresgid16 /* 170 */ - .long sys_getresgid16 - .long sys_prctl - .long ptregs_rt_sigreturn - .long sys_rt_sigaction - .long sys_rt_sigprocmask /* 175 */ - .long sys_rt_sigpending - .long sys_rt_sigtimedwait - .long sys_rt_sigqueueinfo - .long sys_rt_sigsuspend - .long sys_pread64 /* 180 */ - .long sys_pwrite64 - .long sys_chown16 - .long sys_getcwd - .long sys_capget - .long sys_capset /* 185 */ - .long ptregs_sigaltstack - .long sys_sendfile - .long sys_ni_syscall /* reserved for streams1 */ - .long sys_ni_syscall /* reserved for streams2 */ - .long ptregs_vfork /* 190 */ - .long sys_getrlimit - .long sys_mmap_pgoff - .long sys_truncate64 - .long sys_ftruncate64 - .long sys_stat64 /* 195 */ - .long sys_lstat64 - .long sys_fstat64 - .long sys_lchown - .long sys_getuid - .long sys_getgid /* 200 */ - .long sys_geteuid - .long sys_getegid - .long sys_setreuid - .long sys_setregid - .long sys_getgroups /* 205 */ - .long sys_setgroups - .long sys_fchown - .long sys_setresuid - .long sys_getresuid - .long sys_setresgid /* 210 */ - .long sys_getresgid - .long sys_chown - .long sys_setuid - .long sys_setgid - .long sys_setfsuid /* 215 */ - .long sys_setfsgid - .long sys_pivot_root - .long sys_mincore - .long sys_madvise - .long sys_getdents64 /* 220 */ - .long sys_fcntl64 - .long sys_ni_syscall /* reserved for TUX */ - .long sys_ni_syscall - .long sys_gettid - .long sys_readahead /* 225 */ - .long sys_setxattr - .long sys_lsetxattr - .long sys_fsetxattr - .long sys_getxattr - .long sys_lgetxattr /* 230 */ - .long sys_fgetxattr - .long sys_listxattr - .long sys_llistxattr - .long sys_flistxattr - .long sys_removexattr /* 235 */ - .long sys_lremovexattr - .long sys_fremovexattr - .long sys_tkill - .long sys_sendfile64 - .long sys_futex /* 240 */ - .long sys_sched_setaffinity - .long sys_sched_getaffinity - .long sys_set_thread_area - .long sys_get_thread_area - .long sys_io_setup /* 245 */ - .long sys_io_destroy - .long sys_io_getevents - .long sys_io_submit - .long sys_io_cancel - .long sys_fadvise64 /* 250 */ - .long sys_ni_syscall - .long sys_exit_group - .long sys_lookup_dcookie - .long sys_epoll_create - .long sys_epoll_ctl /* 255 */ - .long sys_epoll_wait - .long sys_remap_file_pages - .long sys_set_tid_address - .long sys_timer_create - .long sys_timer_settime /* 260 */ - .long sys_timer_gettime - .long sys_timer_getoverrun - .long sys_timer_delete - .long sys_clock_settime - .long sys_clock_gettime /* 265 */ - .long sys_clock_getres - .long sys_clock_nanosleep - .long sys_statfs64 - .long sys_fstatfs64 - .long sys_tgkill /* 270 */ - .long sys_utimes - .long sys_fadvise64_64 - .long sys_ni_syscall /* sys_vserver */ - .long sys_mbind - .long sys_get_mempolicy - .long sys_set_mempolicy - .long sys_mq_open - .long sys_mq_unlink - .long sys_mq_timedsend - .long sys_mq_timedreceive /* 280 */ - .long sys_mq_notify - .long sys_mq_getsetattr - .long sys_kexec_load - .long sys_waitid - .long sys_ni_syscall /* 285 */ /* available */ - .long sys_add_key - .long sys_request_key - .long sys_keyctl - .long sys_ioprio_set - .long sys_ioprio_get /* 290 */ - .long sys_inotify_init - .long sys_inotify_add_watch - .long sys_inotify_rm_watch - .long sys_migrate_pages - .long sys_openat /* 295 */ - .long sys_mkdirat - .long sys_mknodat - .long sys_fchownat - .long sys_futimesat - .long sys_fstatat64 /* 300 */ - .long sys_unlinkat - .long sys_renameat - .long sys_linkat - .long sys_symlinkat - .long sys_readlinkat /* 305 */ - .long sys_fchmodat - .long sys_faccessat - .long sys_pselect6 - .long sys_ppoll - .long sys_unshare /* 310 */ - .long sys_set_robust_list - .long sys_get_robust_list - .long sys_splice - .long sys_sync_file_range - .long sys_tee /* 315 */ - .long sys_vmsplice - .long sys_move_pages - .long sys_getcpu - .long sys_epoll_pwait - .long sys_utimensat /* 320 */ - .long sys_signalfd - .long sys_timerfd_create - .long sys_eventfd - .long sys_fallocate - .long sys_timerfd_settime /* 325 */ - .long sys_timerfd_gettime - .long sys_signalfd4 - .long sys_eventfd2 - .long sys_epoll_create1 - .long sys_dup3 /* 330 */ - .long sys_pipe2 - .long sys_inotify_init1 - .long sys_preadv - .long sys_pwritev - .long sys_rt_tgsigqueueinfo /* 335 */ - .long sys_perf_event_open - .long sys_recvmmsg - .long sys_fanotify_init - .long sys_fanotify_mark - .long sys_prlimit64 /* 340 */ - .long sys_name_to_handle_at - .long sys_open_by_handle_at - .long sys_clock_adjtime - .long sys_syncfs - .long sys_sendmmsg /* 345 */ - .long sys_setns - .long sys_process_vm_readv - .long sys_process_vm_writev -- cgit v0.10.2 From a9dd5d631729eea8686703fbb25a7a9d4c75a724 Mon Sep 17 00:00:00 2001 From: Rabin Vincent Date: Fri, 18 Nov 2011 17:05:29 +0530 Subject: ktest: Save test output The test output may contain useful information; save it along with the already-saved buildlog, dmesg, and .config. Link: http://lkml.kernel.org/r/1321616131-21352-1-git-send-email-rabin@rab.in Signed-off-by: Rabin Vincent Signed-off-by: Steven Rostedt diff --git a/tools/testing/ktest/ktest.pl b/tools/testing/ktest/ktest.pl index 8b4c253..e93c21c 100755 --- a/tools/testing/ktest/ktest.pl +++ b/tools/testing/ktest/ktest.pl @@ -103,6 +103,7 @@ my $in_patchcheck = 0; my $run_test; my $redirect; my $buildlog; +my $testlog; my $dmesg; my $monitor_fp; my $monitor_pid; @@ -1021,17 +1022,19 @@ sub fail { mkpath($faildir) or die "can't create $faildir"; } - if (-f "$output_config") { - cp "$output_config", "$faildir/config" or - die "failed to copy .config"; - } - if (-f $buildlog) { - cp $buildlog, "$faildir/buildlog" or - die "failed to move $buildlog"; - } - if (-f $dmesg) { - cp $dmesg, "$faildir/dmesg" or - die "failed to move $dmesg"; + + my %files = ( + "config" => $output_config, + "buildlog" => $buildlog, + "dmesg" => $dmesg, + "testlog" => $testlog, + ); + + while (my ($name, $source) = each(%files)) { + if (-f "$source") { + cp "$source", "$faildir/$name" or + die "failed to copy $source"; + } } doprint "*** Saved info to $faildir ***\n"; @@ -1669,7 +1672,10 @@ sub child_run_test { $poweroff_on_error = 0; $die_on_failure = 1; + $redirect = "$testlog"; run_command $run_test or $failed = 1; + undef $redirect; + exit $failed; } @@ -3169,6 +3175,7 @@ for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) { $target = "$ssh_user\@$machine"; $buildlog = "$tmpdir/buildlog-$machine"; + $testlog = "$tmpdir/testlog-$machine"; $dmesg = "$tmpdir/dmesg-$machine"; $make = "$makecmd O=$outputdir"; $output_config = "$outputdir/.config"; @@ -3205,6 +3212,7 @@ for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) { unlink $dmesg; unlink $buildlog; + unlink $testlog; if (defined($addconfig)) { my $min = $minconfig; -- cgit v0.10.2 From de5b6e3bf5e71532057fb4f1eb8ee29c5c7f11db Mon Sep 17 00:00:00 2001 From: Rabin Vincent Date: Fri, 18 Nov 2011 17:05:31 +0530 Subject: ktest: Allow success logs to be stored Add a STORE_SUCCESSES option, to allow success logs to be stored, for example to double-check or otherwise post-process the test logs. Link: http://lkml.kernel.org/r/1321616131-21352-3-git-send-email-rabin@rab.in Signed-off-by: Rabin Vincent Signed-off-by: Steven Rostedt diff --git a/tools/testing/ktest/ktest.pl b/tools/testing/ktest/ktest.pl index e93c21c..6ef104e 100755 --- a/tools/testing/ktest/ktest.pl +++ b/tools/testing/ktest/ktest.pl @@ -113,6 +113,7 @@ my $bisect_sleep_time; my $patchcheck_sleep_time; my $ignore_warnings; my $store_failures; +my $store_successes; my $test_name; my $timeout; my $booted_timeout; @@ -976,6 +977,43 @@ sub wait_for_monitor { print "** Monitor flushed **\n"; } +sub save_logs { + my ($result, $basedir) = @_; + my @t = localtime; + my $date = sprintf "%04d%02d%02d%02d%02d%02d", + 1900+$t[5],$t[4],$t[3],$t[2],$t[1],$t[0]; + + my $type = $build_type; + if ($type =~ /useconfig/) { + $type = "useconfig"; + } + + my $dir = "$machine-$test_type-$type-$result-$date"; + + $dir = "$basedir/$dir"; + + if (!-d $dir) { + mkpath($dir) or + die "can't create $dir"; + } + + my %files = ( + "config" => $output_config, + "buildlog" => $buildlog, + "dmesg" => $dmesg, + "testlog" => $testlog, + ); + + while (my ($name, $source) = each(%files)) { + if (-f "$source") { + cp "$source", "$dir/$name" or + die "failed to copy $source"; + } + } + + doprint "*** Saved info to $dir ***\n"; +} + sub fail { if ($die_on_failure) { @@ -1004,40 +1042,9 @@ sub fail { doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n"; doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n"; - return 1 if (!defined($store_failures)); - - my @t = localtime; - my $date = sprintf "%04d%02d%02d%02d%02d%02d", - 1900+$t[5],$t[4],$t[3],$t[2],$t[1],$t[0]; - - my $type = $build_type; - if ($type =~ /useconfig/) { - $type = "useconfig"; - } - - my $dir = "$machine-$test_type-$type-fail-$date"; - my $faildir = "$store_failures/$dir"; - - if (!-d $faildir) { - mkpath($faildir) or - die "can't create $faildir"; - } - - my %files = ( - "config" => $output_config, - "buildlog" => $buildlog, - "dmesg" => $dmesg, - "testlog" => $testlog, - ); - - while (my ($name, $source) = each(%files)) { - if (-f "$source") { - cp "$source", "$faildir/$name" or - die "failed to copy $source"; - } - } - - doprint "*** Saved info to $faildir ***\n"; + if (defined($store_failures)) { + save_logs "fail", $store_failures; + } return 1; } @@ -1643,6 +1650,10 @@ sub success { doprint "*******************************************\n"; doprint "*******************************************\n"; + if (defined($store_successes)) { + save_logs "success", $store_successes; + } + if ($i != $opt{"NUM_TESTS"} && !do_not_reboot) { doprint "Reboot and wait $sleep_time seconds\n"; reboot $sleep_time; @@ -3137,6 +3148,7 @@ for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) { $bisect_skip = set_test_option("BISECT_SKIP", $i); $config_bisect_good = set_test_option("CONFIG_BISECT_GOOD", $i); $store_failures = set_test_option("STORE_FAILURES", $i); + $store_successes = set_test_option("STORE_SUCCESSES", $i); $test_name = set_test_option("TEST_NAME", $i); $timeout = set_test_option("TIMEOUT", $i); $booted_timeout = set_test_option("BOOTED_TIMEOUT", $i); diff --git a/tools/testing/ktest/sample.conf b/tools/testing/ktest/sample.conf index dbedfa1..42e0eb9 100644 --- a/tools/testing/ktest/sample.conf +++ b/tools/testing/ktest/sample.conf @@ -589,6 +589,12 @@ # (default undefined) #STORE_FAILURES = /home/test/failures +# Directory to store success directories on success. If this is not +# set, the .config, dmesg and bootlog will not be saved if a +# test succeeds. +# (default undefined) +#STORE_SUCCESSES = /home/test/successes + # Build without doing a make mrproper, or removing .config # (default 0) #BUILD_NOCLEAN = 0 -- cgit v0.10.2 From 97e36834f5a106459ab1b290e663a4eb6264639e Mon Sep 17 00:00:00 2001 From: Konrad Rzeszutek Wilk Date: Wed, 12 Oct 2011 12:12:36 -0400 Subject: xen/blk[front|back]: Squash blkif_request_rw and blkif_request_discard together In a union type structure to deal with the overlapping attributes in a easier manner. Suggested-by: Ian Campbell Signed-off-by: Konrad Rzeszutek Wilk diff --git a/drivers/block/xen-blkback/blkback.c b/drivers/block/xen-blkback/blkback.c index 15ec4db..d7104ab 100644 --- a/drivers/block/xen-blkback/blkback.c +++ b/drivers/block/xen-blkback/blkback.c @@ -362,7 +362,7 @@ static int xen_blkbk_map(struct blkif_request *req, { struct gnttab_map_grant_ref map[BLKIF_MAX_SEGMENTS_PER_REQUEST]; int i; - int nseg = req->nr_segments; + int nseg = req->u.rw.nr_segments; int ret = 0; /* @@ -449,7 +449,7 @@ static void xen_blk_discard(struct xen_blkif *blkif, struct blkif_request *req) } else if (err) status = BLKIF_RSP_ERROR; - make_response(blkif, req->id, req->operation, status); + make_response(blkif, req->u.discard.id, req->operation, status); } static void xen_blk_drain_io(struct xen_blkif *blkif) @@ -644,7 +644,8 @@ static int dispatch_rw_block_io(struct xen_blkif *blkif, } /* Check that the number of segments is sane. */ - nseg = req->nr_segments; + nseg = req->u.rw.nr_segments; + if (unlikely(nseg == 0 && operation != WRITE_FLUSH && operation != REQ_DISCARD) || unlikely(nseg > BLKIF_MAX_SEGMENTS_PER_REQUEST)) { @@ -654,12 +655,12 @@ static int dispatch_rw_block_io(struct xen_blkif *blkif, goto fail_response; } - preq.dev = req->handle; + preq.dev = req->u.rw.handle; preq.sector_number = req->u.rw.sector_number; preq.nr_sects = 0; pending_req->blkif = blkif; - pending_req->id = req->id; + pending_req->id = req->u.rw.id; pending_req->operation = req->operation; pending_req->status = BLKIF_RSP_OKAY; pending_req->nr_pages = nseg; @@ -784,7 +785,7 @@ static int dispatch_rw_block_io(struct xen_blkif *blkif, xen_blkbk_unmap(pending_req); fail_response: /* Haven't submitted any bio's yet. */ - make_response(blkif, req->id, req->operation, BLKIF_RSP_ERROR); + make_response(blkif, req->u.rw.id, req->operation, BLKIF_RSP_ERROR); free_req(pending_req); msleep(1); /* back off a bit */ return -EIO; diff --git a/drivers/block/xen-blkback/common.h b/drivers/block/xen-blkback/common.h index dfb1b3a..dbfe7b3 100644 --- a/drivers/block/xen-blkback/common.h +++ b/drivers/block/xen-blkback/common.h @@ -60,58 +60,66 @@ struct blkif_common_response { char dummy; }; -/* i386 protocol version */ -#pragma pack(push, 4) - struct blkif_x86_32_request_rw { + uint8_t nr_segments; /* number of segments */ + blkif_vdev_t handle; /* only for read/write requests */ + uint64_t id; /* private guest value, echoed in resp */ blkif_sector_t sector_number;/* start sector idx on disk (r/w only) */ struct blkif_request_segment seg[BLKIF_MAX_SEGMENTS_PER_REQUEST]; -}; +} __attribute__((__packed__)); struct blkif_x86_32_request_discard { + uint8_t nr_segments; /* number of segments */ + blkif_vdev_t _pad1; /* was "handle" for read/write requests */ + uint64_t id; /* private guest value, echoed in resp */ blkif_sector_t sector_number;/* start sector idx on disk (r/w only) */ - uint64_t nr_sectors; -}; + uint64_t nr_sectors; +} __attribute__((__packed__)); struct blkif_x86_32_request { uint8_t operation; /* BLKIF_OP_??? */ - uint8_t nr_segments; /* number of segments */ - blkif_vdev_t handle; /* only for read/write requests */ - uint64_t id; /* private guest value, echoed in resp */ union { struct blkif_x86_32_request_rw rw; struct blkif_x86_32_request_discard discard; } u; -}; +} __attribute__((__packed__)); + +/* i386 protocol version */ +#pragma pack(push, 4) struct blkif_x86_32_response { uint64_t id; /* copied from request */ uint8_t operation; /* copied from request */ int16_t status; /* BLKIF_RSP_??? */ }; #pragma pack(pop) - /* x86_64 protocol version */ struct blkif_x86_64_request_rw { + uint8_t nr_segments; /* number of segments */ + blkif_vdev_t handle; /* only for read/write requests */ + uint32_t _pad1; /* offsetof(blkif_reqest..,u.rw.id)==8 */ + uint64_t id; blkif_sector_t sector_number;/* start sector idx on disk (r/w only) */ struct blkif_request_segment seg[BLKIF_MAX_SEGMENTS_PER_REQUEST]; -}; +} __attribute__((__packed__)); struct blkif_x86_64_request_discard { + uint8_t nr_segments; /* number of segments */ + blkif_vdev_t _pad1; /* was "handle" for read/write requests */ + uint32_t _pad2; /* offsetof(blkif_..,u.discard.id)==8 */ + uint64_t id; blkif_sector_t sector_number;/* start sector idx on disk (r/w only) */ - uint64_t nr_sectors; -}; + uint64_t nr_sectors; +} __attribute__((__packed__)); struct blkif_x86_64_request { uint8_t operation; /* BLKIF_OP_??? */ - uint8_t nr_segments; /* number of segments */ - blkif_vdev_t handle; /* only for read/write requests */ - uint64_t __attribute__((__aligned__(8))) id; union { struct blkif_x86_64_request_rw rw; struct blkif_x86_64_request_discard discard; } u; -}; +} __attribute__((__packed__)); + struct blkif_x86_64_response { uint64_t __attribute__((__aligned__(8))) id; uint8_t operation; /* copied from request */ @@ -237,18 +245,18 @@ static inline void blkif_get_x86_32_req(struct blkif_request *dst, { int i, n = BLKIF_MAX_SEGMENTS_PER_REQUEST; dst->operation = src->operation; - dst->nr_segments = src->nr_segments; - dst->handle = src->handle; - dst->id = src->id; switch (src->operation) { case BLKIF_OP_READ: case BLKIF_OP_WRITE: case BLKIF_OP_WRITE_BARRIER: case BLKIF_OP_FLUSH_DISKCACHE: + dst->u.rw.nr_segments = src->u.rw.nr_segments; + dst->u.rw.handle = src->u.rw.handle; + dst->u.rw.id = src->u.rw.id; dst->u.rw.sector_number = src->u.rw.sector_number; barrier(); - if (n > dst->nr_segments) - n = dst->nr_segments; + if (n > dst->u.rw.nr_segments) + n = dst->u.rw.nr_segments; for (i = 0; i < n; i++) dst->u.rw.seg[i] = src->u.rw.seg[i]; break; @@ -266,18 +274,18 @@ static inline void blkif_get_x86_64_req(struct blkif_request *dst, { int i, n = BLKIF_MAX_SEGMENTS_PER_REQUEST; dst->operation = src->operation; - dst->nr_segments = src->nr_segments; - dst->handle = src->handle; - dst->id = src->id; switch (src->operation) { case BLKIF_OP_READ: case BLKIF_OP_WRITE: case BLKIF_OP_WRITE_BARRIER: case BLKIF_OP_FLUSH_DISKCACHE: + dst->u.rw.nr_segments = src->u.rw.nr_segments; + dst->u.rw.handle = src->u.rw.handle; + dst->u.rw.id = src->u.rw.id; dst->u.rw.sector_number = src->u.rw.sector_number; barrier(); - if (n > dst->nr_segments) - n = dst->nr_segments; + if (n > dst->u.rw.nr_segments) + n = dst->u.rw.nr_segments; for (i = 0; i < n; i++) dst->u.rw.seg[i] = src->u.rw.seg[i]; break; diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c index 7b2ec59..2c2c4be 100644 --- a/drivers/block/xen-blkfront.c +++ b/drivers/block/xen-blkfront.c @@ -135,15 +135,15 @@ static int get_id_from_freelist(struct blkfront_info *info) { unsigned long free = info->shadow_free; BUG_ON(free >= BLK_RING_SIZE); - info->shadow_free = info->shadow[free].req.id; - info->shadow[free].req.id = 0x0fffffee; /* debug */ + info->shadow_free = info->shadow[free].req.u.rw.id; + info->shadow[free].req.u.rw.id = 0x0fffffee; /* debug */ return free; } static void add_id_to_freelist(struct blkfront_info *info, unsigned long id) { - info->shadow[id].req.id = info->shadow_free; + info->shadow[id].req.u.rw.id = info->shadow_free; info->shadow[id].request = NULL; info->shadow_free = id; } @@ -287,9 +287,9 @@ static int blkif_queue_request(struct request *req) id = get_id_from_freelist(info); info->shadow[id].request = req; - ring_req->id = id; + ring_req->u.rw.id = id; ring_req->u.rw.sector_number = (blkif_sector_t)blk_rq_pos(req); - ring_req->handle = info->handle; + ring_req->u.rw.handle = info->handle; ring_req->operation = rq_data_dir(req) ? BLKIF_OP_WRITE : BLKIF_OP_READ; @@ -308,13 +308,15 @@ static int blkif_queue_request(struct request *req) if (unlikely(req->cmd_flags & REQ_DISCARD)) { /* id, sector_number and handle are set above. */ ring_req->operation = BLKIF_OP_DISCARD; - ring_req->nr_segments = 0; + ring_req->u.discard.nr_segments = 0; ring_req->u.discard.nr_sectors = blk_rq_sectors(req); } else { - ring_req->nr_segments = blk_rq_map_sg(req->q, req, info->sg); - BUG_ON(ring_req->nr_segments > BLKIF_MAX_SEGMENTS_PER_REQUEST); + ring_req->u.rw.nr_segments = blk_rq_map_sg(req->q, req, + info->sg); + BUG_ON(ring_req->u.rw.nr_segments > + BLKIF_MAX_SEGMENTS_PER_REQUEST); - for_each_sg(info->sg, sg, ring_req->nr_segments, i) { + for_each_sg(info->sg, sg, ring_req->u.rw.nr_segments, i) { buffer_mfn = pfn_to_mfn(page_to_pfn(sg_page(sg))); fsect = sg->offset >> 9; lsect = fsect + (sg->length >> 9) - 1; @@ -705,7 +707,7 @@ static void blkif_free(struct blkfront_info *info, int suspend) static void blkif_completion(struct blk_shadow *s) { int i; - for (i = 0; i < s->req.nr_segments; i++) + for (i = 0; i < s->req.u.rw.nr_segments; i++) gnttab_end_foreign_access(s->req.u.rw.seg[i].gref, 0, 0UL); } @@ -763,7 +765,7 @@ static irqreturn_t blkif_interrupt(int irq, void *dev_id) error = -EOPNOTSUPP; } if (unlikely(bret->status == BLKIF_RSP_ERROR && - info->shadow[id].req.nr_segments == 0)) { + info->shadow[id].req.u.rw.nr_segments == 0)) { printk(KERN_WARNING "blkfront: %s: empty write %s op failed\n", info->flush_op == BLKIF_OP_WRITE_BARRIER ? "barrier" : "flush disk cache", @@ -984,8 +986,8 @@ static int blkfront_probe(struct xenbus_device *dev, INIT_WORK(&info->work, blkif_restart_queue); for (i = 0; i < BLK_RING_SIZE; i++) - info->shadow[i].req.id = i+1; - info->shadow[BLK_RING_SIZE-1].req.id = 0x0fffffff; + info->shadow[i].req.u.rw.id = i+1; + info->shadow[BLK_RING_SIZE-1].req.u.rw.id = 0x0fffffff; /* Front end dir is a number, which is used as the id. */ info->handle = simple_strtoul(strrchr(dev->nodename, '/')+1, NULL, 0); @@ -1019,9 +1021,9 @@ static int blkif_recover(struct blkfront_info *info) /* Stage 2: Set up free list. */ memset(&info->shadow, 0, sizeof(info->shadow)); for (i = 0; i < BLK_RING_SIZE; i++) - info->shadow[i].req.id = i+1; + info->shadow[i].req.u.rw.id = i+1; info->shadow_free = info->ring.req_prod_pvt; - info->shadow[BLK_RING_SIZE-1].req.id = 0x0fffffff; + info->shadow[BLK_RING_SIZE-1].req.u.rw.id = 0x0fffffff; /* Stage 3: Find pending requests and requeue them. */ for (i = 0; i < BLK_RING_SIZE; i++) { @@ -1034,17 +1036,17 @@ static int blkif_recover(struct blkfront_info *info) *req = copy[i].req; /* We get a new request id, and must reset the shadow state. */ - req->id = get_id_from_freelist(info); - memcpy(&info->shadow[req->id], ©[i], sizeof(copy[i])); + req->u.rw.id = get_id_from_freelist(info); + memcpy(&info->shadow[req->u.rw.id], ©[i], sizeof(copy[i])); /* Rewrite any grant references invalidated by susp/resume. */ - for (j = 0; j < req->nr_segments; j++) + for (j = 0; j < req->u.rw.nr_segments; j++) gnttab_grant_foreign_access_ref( req->u.rw.seg[j].gref, info->xbdev->otherend_id, - pfn_to_mfn(info->shadow[req->id].frame[j]), - rq_data_dir(info->shadow[req->id].request)); - info->shadow[req->id].req = *req; + pfn_to_mfn(info->shadow[req->u.rw.id].frame[j]), + rq_data_dir(info->shadow[req->u.rw.id].request)); + info->shadow[req->u.rw.id].req = *req; info->ring.req_prod_pvt++; } diff --git a/include/xen/interface/io/blkif.h b/include/xen/interface/io/blkif.h index 9324488..f88e28b 100644 --- a/include/xen/interface/io/blkif.h +++ b/include/xen/interface/io/blkif.h @@ -95,6 +95,12 @@ typedef uint64_t blkif_sector_t; #define BLKIF_MAX_SEGMENTS_PER_REQUEST 11 struct blkif_request_rw { + uint8_t nr_segments; /* number of segments */ + blkif_vdev_t handle; /* only for read/write requests */ +#ifdef CONFIG_X86_64 + uint32_t _pad1; /* offsetof(blkif_request,u.rw.id) == 8 */ +#endif + uint64_t id; /* private guest value, echoed in resp */ blkif_sector_t sector_number;/* start sector idx on disk (r/w only) */ struct blkif_request_segment { grant_ref_t gref; /* reference to I/O buffer frame */ @@ -102,23 +108,27 @@ struct blkif_request_rw { /* @last_sect: last sector in frame to transfer (inclusive). */ uint8_t first_sect, last_sect; } seg[BLKIF_MAX_SEGMENTS_PER_REQUEST]; -}; +} __attribute__((__packed__)); struct blkif_request_discard { + uint8_t nr_segments; /* number of segments */ + blkif_vdev_t _pad1; /* only for read/write requests */ +#ifdef CONFIG_X86_64 + uint32_t _pad2; /* offsetof(blkif_req..,u.discard.id)==8*/ +#endif + uint64_t id; /* private guest value, echoed in resp */ blkif_sector_t sector_number; - uint64_t nr_sectors; -}; + uint64_t nr_sectors; + uint8_t _pad3; +} __attribute__((__packed__)); struct blkif_request { uint8_t operation; /* BLKIF_OP_??? */ - uint8_t nr_segments; /* number of segments */ - blkif_vdev_t handle; /* only for read/write requests */ - uint64_t id; /* private guest value, echoed in resp */ union { struct blkif_request_rw rw; struct blkif_request_discard discard; } u; -}; +} __attribute__((__packed__)); struct blkif_response { uint64_t id; /* copied from request */ -- cgit v0.10.2 From 5ea42986694a96542644f9cae8b122d3a00c508f Mon Sep 17 00:00:00 2001 From: Konrad Rzeszutek Wilk Date: Wed, 12 Oct 2011 16:23:30 -0400 Subject: xen/blk[front|back]: Enhance discard support with secure erasing support. Part of the blkdev_issue_discard(xx) operation is that it can also issue a secure discard operation that will permanantly remove the sectors in question. We advertise that we can support that via the 'discard-secure' attribute and on the request, if the 'secure' bit is set, we will attempt to pass in REQ_DISCARD | REQ_SECURE. CC: Li Dongyang [v1: Used 'flag' instead of 'secure:1' bit] [v2: Use 'reserved' uint8_t instead of adding a new value] [v3: Check for nseg when mapping instead of operation] Signed-off-by: Konrad Rzeszutek Wilk diff --git a/drivers/block/xen-blkback/blkback.c b/drivers/block/xen-blkback/blkback.c index d7104ab..9d2261b 100644 --- a/drivers/block/xen-blkback/blkback.c +++ b/drivers/block/xen-blkback/blkback.c @@ -422,13 +422,16 @@ static void xen_blk_discard(struct xen_blkif *blkif, struct blkif_request *req) int status = BLKIF_RSP_OKAY; struct block_device *bdev = blkif->vbd.bdev; - if (blkif->blk_backend_type == BLKIF_BACKEND_PHY) + if (blkif->blk_backend_type == BLKIF_BACKEND_PHY) { + unsigned long secure = (blkif->vbd.discard_secure && + (req->u.discard.flag & BLKIF_DISCARD_SECURE)) ? + BLKDEV_DISCARD_SECURE : 0; /* just forward the discard request */ err = blkdev_issue_discard(bdev, req->u.discard.sector_number, req->u.discard.nr_sectors, - GFP_KERNEL, 0); - else if (blkif->blk_backend_type == BLKIF_BACKEND_FILE) { + GFP_KERNEL, secure); + } else if (blkif->blk_backend_type == BLKIF_BACKEND_FILE) { /* punch a hole in the backing file */ struct loop_device *lo = bdev->bd_disk->private_data; struct file *file = lo->lo_backing_file; @@ -643,8 +646,11 @@ static int dispatch_rw_block_io(struct xen_blkif *blkif, break; } - /* Check that the number of segments is sane. */ - nseg = req->u.rw.nr_segments; + if (unlikely(operation == REQ_DISCARD)) + nseg = 0; + else + /* Check that the number of segments is sane. */ + nseg = req->u.rw.nr_segments; if (unlikely(nseg == 0 && operation != WRITE_FLUSH && operation != REQ_DISCARD) || @@ -708,7 +714,7 @@ static int dispatch_rw_block_io(struct xen_blkif *blkif, * the hypercall to unmap the grants - that is all done in * xen_blkbk_unmap. */ - if (operation != REQ_DISCARD && xen_blkbk_map(req, pending_req, seg)) + if (nseg && xen_blkbk_map(req, pending_req, seg)) goto fail_flush; /* diff --git a/drivers/block/xen-blkback/common.h b/drivers/block/xen-blkback/common.h index dbfe7b3..d0ee7ed 100644 --- a/drivers/block/xen-blkback/common.h +++ b/drivers/block/xen-blkback/common.h @@ -69,7 +69,7 @@ struct blkif_x86_32_request_rw { } __attribute__((__packed__)); struct blkif_x86_32_request_discard { - uint8_t nr_segments; /* number of segments */ + uint8_t flag; /* BLKIF_DISCARD_SECURE or zero */ blkif_vdev_t _pad1; /* was "handle" for read/write requests */ uint64_t id; /* private guest value, echoed in resp */ blkif_sector_t sector_number;/* start sector idx on disk (r/w only) */ @@ -104,7 +104,7 @@ struct blkif_x86_64_request_rw { } __attribute__((__packed__)); struct blkif_x86_64_request_discard { - uint8_t nr_segments; /* number of segments */ + uint8_t flag; /* BLKIF_DISCARD_SECURE or zero */ blkif_vdev_t _pad1; /* was "handle" for read/write requests */ uint32_t _pad2; /* offsetof(blkif_..,u.discard.id)==8 */ uint64_t id; @@ -164,6 +164,7 @@ struct xen_vbd { /* Cached size parameter. */ sector_t size; bool flush_support; + bool discard_secure; }; struct backend_info; @@ -261,6 +262,7 @@ static inline void blkif_get_x86_32_req(struct blkif_request *dst, dst->u.rw.seg[i] = src->u.rw.seg[i]; break; case BLKIF_OP_DISCARD: + dst->u.discard.flag = src->u.discard.flag; dst->u.discard.sector_number = src->u.discard.sector_number; dst->u.discard.nr_sectors = src->u.discard.nr_sectors; break; @@ -290,6 +292,7 @@ static inline void blkif_get_x86_64_req(struct blkif_request *dst, dst->u.rw.seg[i] = src->u.rw.seg[i]; break; case BLKIF_OP_DISCARD: + dst->u.discard.flag = src->u.discard.flag; dst->u.discard.sector_number = src->u.discard.sector_number; dst->u.discard.nr_sectors = src->u.discard.nr_sectors; break; diff --git a/drivers/block/xen-blkback/xenbus.c b/drivers/block/xen-blkback/xenbus.c index f759ad4..187fd2c 100644 --- a/drivers/block/xen-blkback/xenbus.c +++ b/drivers/block/xen-blkback/xenbus.c @@ -338,6 +338,9 @@ static int xen_vbd_create(struct xen_blkif *blkif, blkif_vdev_t handle, if (q && q->flush_flags) vbd->flush_support = true; + if (q && blk_queue_secdiscard(q)) + vbd->discard_secure = true; + DPRINTK("Successful creation of handle=%04x (dom=%u)\n", handle, blkif->domid); return 0; @@ -420,6 +423,15 @@ int xen_blkbk_discard(struct xenbus_transaction xbt, struct backend_info *be) state = 1; blkif->blk_backend_type = BLKIF_BACKEND_PHY; } + /* Optional. */ + err = xenbus_printf(xbt, dev->nodename, + "discard-secure", "%d", + blkif->vbd.discard_secure); + if (err) { + xenbus_dev_fatal(dev, err, + "writting discard-secure"); + goto kfree; + } } } else { err = PTR_ERR(type); diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c index 2c2c4be..351ddef 100644 --- a/drivers/block/xen-blkfront.c +++ b/drivers/block/xen-blkfront.c @@ -98,7 +98,8 @@ struct blkfront_info unsigned long shadow_free; unsigned int feature_flush; unsigned int flush_op; - unsigned int feature_discard; + unsigned int feature_discard:1; + unsigned int feature_secdiscard:1; unsigned int discard_granularity; unsigned int discard_alignment; int is_ready; @@ -305,11 +306,14 @@ static int blkif_queue_request(struct request *req) ring_req->operation = info->flush_op; } - if (unlikely(req->cmd_flags & REQ_DISCARD)) { + if (unlikely(req->cmd_flags & (REQ_DISCARD | REQ_SECURE))) { /* id, sector_number and handle are set above. */ ring_req->operation = BLKIF_OP_DISCARD; - ring_req->u.discard.nr_segments = 0; ring_req->u.discard.nr_sectors = blk_rq_sectors(req); + if ((req->cmd_flags & REQ_SECURE) && info->feature_secdiscard) + ring_req->u.discard.flag = BLKIF_DISCARD_SECURE; + else + ring_req->u.discard.flag = 0; } else { ring_req->u.rw.nr_segments = blk_rq_map_sg(req->q, req, info->sg); @@ -426,6 +430,8 @@ static int xlvbd_init_blk_queue(struct gendisk *gd, u16 sector_size) blk_queue_max_discard_sectors(rq, get_capacity(gd)); rq->limits.discard_granularity = info->discard_granularity; rq->limits.discard_alignment = info->discard_alignment; + if (info->feature_secdiscard) + queue_flag_set_unlocked(QUEUE_FLAG_SECDISCARD, rq); } /* Hard sector size and max sectors impersonate the equiv. hardware. */ @@ -707,6 +713,8 @@ static void blkif_free(struct blkfront_info *info, int suspend) static void blkif_completion(struct blk_shadow *s) { int i; + /* Do not let BLKIF_OP_DISCARD as nr_segment is in the same place + * flag. */ for (i = 0; i < s->req.u.rw.nr_segments; i++) gnttab_end_foreign_access(s->req.u.rw.seg[i].gref, 0, 0UL); } @@ -738,7 +746,8 @@ static irqreturn_t blkif_interrupt(int irq, void *dev_id) id = bret->id; req = info->shadow[id].request; - blkif_completion(&info->shadow[id]); + if (bret->operation != BLKIF_OP_DISCARD) + blkif_completion(&info->shadow[id]); add_id_to_freelist(info, id); @@ -751,7 +760,9 @@ static irqreturn_t blkif_interrupt(int irq, void *dev_id) info->gd->disk_name); error = -EOPNOTSUPP; info->feature_discard = 0; + info->feature_secdiscard = 0; queue_flag_clear(QUEUE_FLAG_DISCARD, rq); + queue_flag_clear(QUEUE_FLAG_SECDISCARD, rq); } __blk_end_request_all(req, error); break; @@ -1039,13 +1050,15 @@ static int blkif_recover(struct blkfront_info *info) req->u.rw.id = get_id_from_freelist(info); memcpy(&info->shadow[req->u.rw.id], ©[i], sizeof(copy[i])); + if (req->operation != BLKIF_OP_DISCARD) { /* Rewrite any grant references invalidated by susp/resume. */ - for (j = 0; j < req->u.rw.nr_segments; j++) - gnttab_grant_foreign_access_ref( - req->u.rw.seg[j].gref, - info->xbdev->otherend_id, - pfn_to_mfn(info->shadow[req->u.rw.id].frame[j]), - rq_data_dir(info->shadow[req->u.rw.id].request)); + for (j = 0; j < req->u.rw.nr_segments; j++) + gnttab_grant_foreign_access_ref( + req->u.rw.seg[j].gref, + info->xbdev->otherend_id, + pfn_to_mfn(info->shadow[req->u.rw.id].frame[j]), + rq_data_dir(info->shadow[req->u.rw.id].request)); + } info->shadow[req->u.rw.id].req = *req; info->ring.req_prod_pvt++; @@ -1137,11 +1150,13 @@ static void blkfront_setup_discard(struct blkfront_info *info) char *type; unsigned int discard_granularity; unsigned int discard_alignment; + unsigned int discard_secure; type = xenbus_read(XBT_NIL, info->xbdev->otherend, "type", NULL); if (IS_ERR(type)) return; + info->feature_secdiscard = 0; if (strncmp(type, "phy", 3) == 0) { err = xenbus_gather(XBT_NIL, info->xbdev->otherend, "discard-granularity", "%u", &discard_granularity, @@ -1152,6 +1167,12 @@ static void blkfront_setup_discard(struct blkfront_info *info) info->discard_granularity = discard_granularity; info->discard_alignment = discard_alignment; } + err = xenbus_gather(XBT_NIL, info->xbdev->otherend, + "discard-secure", "%d", &discard_secure, + NULL); + if (!err) + info->feature_secdiscard = discard_secure; + } else if (strncmp(type, "file", 4) == 0) info->feature_discard = 1; diff --git a/include/xen/interface/io/blkif.h b/include/xen/interface/io/blkif.h index f88e28b..ee338bf 100644 --- a/include/xen/interface/io/blkif.h +++ b/include/xen/interface/io/blkif.h @@ -84,6 +84,21 @@ typedef uint64_t blkif_sector_t; * e07154r6-Data_Set_Management_Proposal_for_ATA-ACS2.doc * http://www.seagate.com/staticfiles/support/disc/manuals/ * Interface%20manuals/100293068c.pdf + * The backend can optionally provide three extra XenBus attributes to + * further optimize the discard functionality: + * 'discard-aligment' - Devices that support discard functionality may + * internally allocate space in units that are bigger than the exported + * logical block size. The discard-alignment parameter indicates how many bytes + * the beginning of the partition is offset from the internal allocation unit's + * natural alignment. + * 'discard-granularity' - Devices that support discard functionality may + * internally allocate space using units that are bigger than the logical block + * size. The discard-granularity parameter indicates the size of the internal + * allocation unit in bytes if reported by the device. Otherwise the + * discard-granularity will be set to match the device's physical block size. + * 'discard-secure' - All copies of the discarded sectors (potentially created + * by garbage collection) must also be erased. To use this feature, the flag + * BLKIF_DISCARD_SECURE must be set in the blkif_request_trim. */ #define BLKIF_OP_DISCARD 5 @@ -111,7 +126,8 @@ struct blkif_request_rw { } __attribute__((__packed__)); struct blkif_request_discard { - uint8_t nr_segments; /* number of segments */ + uint8_t flag; /* BLKIF_DISCARD_SECURE or zero. */ +#define BLKIF_DISCARD_SECURE (1<<0) /* ignored if discard-secure=0 */ blkif_vdev_t _pad1; /* only for read/write requests */ #ifdef CONFIG_X86_64 uint32_t _pad2; /* offsetof(blkif_req..,u.discard.id)==8*/ -- cgit v0.10.2 From 421463526fd1d8b5cb575baca12667c1005a110b Mon Sep 17 00:00:00 2001 From: Konrad Rzeszutek Wilk Date: Wed, 12 Oct 2011 17:26:47 -0400 Subject: xen/blkback: Move processing of BLKIF_OP_DISCARD from dispatch_rw_block_io .. and move it to its own function that will deal with the discard operation. Signed-off-by: Konrad Rzeszutek Wilk diff --git a/drivers/block/xen-blkback/blkback.c b/drivers/block/xen-blkback/blkback.c index 9d2261b..b058de7 100644 --- a/drivers/block/xen-blkback/blkback.c +++ b/drivers/block/xen-blkback/blkback.c @@ -416,12 +416,16 @@ static int xen_blkbk_map(struct blkif_request *req, return ret; } -static void xen_blk_discard(struct xen_blkif *blkif, struct blkif_request *req) +static int dispatch_discard_io(struct xen_blkif *blkif, + struct blkif_request *req) { int err = 0; int status = BLKIF_RSP_OKAY; struct block_device *bdev = blkif->vbd.bdev; + blkif->st_ds_req++; + + xen_blkif_get(blkif); if (blkif->blk_backend_type == BLKIF_BACKEND_PHY) { unsigned long secure = (blkif->vbd.discard_secure && (req->u.discard.flag & BLKIF_DISCARD_SECURE)) ? @@ -453,6 +457,8 @@ static void xen_blk_discard(struct xen_blkif *blkif, struct blkif_request *req) status = BLKIF_RSP_ERROR; make_response(blkif, req->u.discard.id, req->operation, status); + xen_blkif_put(blkif); + return err; } static void xen_blk_drain_io(struct xen_blkif *blkif) @@ -576,8 +582,11 @@ __do_block_io_op(struct xen_blkif *blkif) /* Apply all sanity checks to /private copy/ of request. */ barrier(); - - if (dispatch_rw_block_io(blkif, &req, pending_req)) + if (unlikely(req.operation == BLKIF_OP_DISCARD)) { + free_req(pending_req); + if (dispatch_discard_io(blkif, &req)) + break; + } else if (dispatch_rw_block_io(blkif, &req, pending_req)) break; /* Yield point for this unbounded loop. */ @@ -636,24 +645,16 @@ static int dispatch_rw_block_io(struct xen_blkif *blkif, blkif->st_f_req++; operation = WRITE_FLUSH; break; - case BLKIF_OP_DISCARD: - blkif->st_ds_req++; - operation = REQ_DISCARD; - break; default: operation = 0; /* make gcc happy */ goto fail_response; break; } - if (unlikely(operation == REQ_DISCARD)) - nseg = 0; - else - /* Check that the number of segments is sane. */ - nseg = req->u.rw.nr_segments; + /* Check that the number of segments is sane. */ + nseg = req->u.rw.nr_segments; - if (unlikely(nseg == 0 && operation != WRITE_FLUSH && - operation != REQ_DISCARD) || + if (unlikely(nseg == 0 && operation != WRITE_FLUSH) || unlikely(nseg > BLKIF_MAX_SEGMENTS_PER_REQUEST)) { pr_debug(DRV_PFX "Bad number of segments in request (%d)\n", nseg); @@ -714,7 +715,7 @@ static int dispatch_rw_block_io(struct xen_blkif *blkif, * the hypercall to unmap the grants - that is all done in * xen_blkbk_unmap. */ - if (nseg && xen_blkbk_map(req, pending_req, seg)) + if (xen_blkbk_map(req, pending_req, seg)) goto fail_flush; /* @@ -746,23 +747,16 @@ static int dispatch_rw_block_io(struct xen_blkif *blkif, /* This will be hit if the operation was a flush or discard. */ if (!bio) { - BUG_ON(operation != WRITE_FLUSH && operation != REQ_DISCARD); + BUG_ON(operation != WRITE_FLUSH); - if (operation == WRITE_FLUSH) { - bio = bio_alloc(GFP_KERNEL, 0); - if (unlikely(bio == NULL)) - goto fail_put_bio; + bio = bio_alloc(GFP_KERNEL, 0); + if (unlikely(bio == NULL)) + goto fail_put_bio; - biolist[nbio++] = bio; - bio->bi_bdev = preq.bdev; - bio->bi_private = pending_req; - bio->bi_end_io = end_block_io_op; - } else if (operation == REQ_DISCARD) { - xen_blk_discard(blkif, req); - xen_blkif_put(blkif); - free_req(pending_req); - return 0; - } + biolist[nbio++] = bio; + bio->bi_bdev = preq.bdev; + bio->bi_private = pending_req; + bio->bi_end_io = end_block_io_op; } /* -- cgit v0.10.2 From ae18be11b5ccc3be9e268592616488c5f9d987f5 Mon Sep 17 00:00:00 2001 From: Li Dongyang Date: Thu, 10 Nov 2011 15:52:06 +0800 Subject: xen-blkback: convert hole punching to discard request on loop devices As of dfaa2ef68e80c378e610e3c8c536f1c239e8d3ef, loop devices support discard request now. We could just issue a discard request, and the loop driver will punch the hole for us, so we don't need to touch the internals of loop device and punch the hole ourselves, Thanks. V0->V1: rebased on devel/for-jens-3.3 Signed-off-by: Li Dongyang Signed-off-by: Konrad Rzeszutek Wilk diff --git a/drivers/block/xen-blkback/blkback.c b/drivers/block/xen-blkback/blkback.c index b058de7..0088bf6 100644 --- a/drivers/block/xen-blkback/blkback.c +++ b/drivers/block/xen-blkback/blkback.c @@ -39,9 +39,6 @@ #include #include #include -#include -#include -#include #include #include @@ -426,27 +423,15 @@ static int dispatch_discard_io(struct xen_blkif *blkif, blkif->st_ds_req++; xen_blkif_get(blkif); - if (blkif->blk_backend_type == BLKIF_BACKEND_PHY) { + if (blkif->blk_backend_type == BLKIF_BACKEND_PHY || + blkif->blk_backend_type == BLKIF_BACKEND_FILE) { unsigned long secure = (blkif->vbd.discard_secure && (req->u.discard.flag & BLKIF_DISCARD_SECURE)) ? BLKDEV_DISCARD_SECURE : 0; - /* just forward the discard request */ err = blkdev_issue_discard(bdev, req->u.discard.sector_number, req->u.discard.nr_sectors, GFP_KERNEL, secure); - } else if (blkif->blk_backend_type == BLKIF_BACKEND_FILE) { - /* punch a hole in the backing file */ - struct loop_device *lo = bdev->bd_disk->private_data; - struct file *file = lo->lo_backing_file; - - if (file->f_op->fallocate) - err = file->f_op->fallocate(file, - FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE, - req->u.discard.sector_number << 9, - req->u.discard.nr_sectors << 9); - else - err = -EOPNOTSUPP; } else err = -EOPNOTSUPP; -- cgit v0.10.2 From f14525f9e033f344996905744f41680ea2b877ce Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Fri, 18 Nov 2011 16:03:27 -0800 Subject: x86: Simplify syscallhdr.sh Simplify syscallhdr.sh by letting grep sort out the ABIs that we want, rather than relying on manual list matching. This is safe since the ABI strings already have to consist only of characters which are valid in C macro names. Suggested-by: Matt Helsley Link: http://lkml.kernel.org/r/20111118221558.GA6408@count0.beaverton.ibm.com Signed-off-by: H. Peter Anvin diff --git a/arch/x86/syscalls/syscallhdr.sh b/arch/x86/syscalls/syscallhdr.sh index 0d473ff..b3c5930 100644 --- a/arch/x86/syscalls/syscallhdr.sh +++ b/arch/x86/syscalls/syscallhdr.sh @@ -2,33 +2,20 @@ in="$1" out="$2" -my_abis=`echo "$3" | tr ',' ' '` +my_abis=`echo "($3)" | tr ',' '|'` prefix="$4" offset="$5" fileguard=_ASM_X86_`basename "$out" | sed \ -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/' \ -e 's/[^A-Z0-9_]/_/g' -e 's/__/_/g'` - -in_list () { - local x - for x in $1; do - if [ x"$x" = x"$2" ]; then - return 0 - fi - done - return 1 -} - -grep '^[0-9]' "$in" | sort -n | ( +grep -E "^[0-9A-Fa-fXx]+[[:space:]]+${my_abis}" "$in" | sort -n | ( echo "#ifndef ${fileguard}" echo "#define ${fileguard} 1" echo "" while read nr abi name entry ; do - if in_list "$my_abis" "$abi"; then - echo "#define __NR_${prefix}${name}" $((nr+offset)) - fi + echo "#define __NR_${prefix}${name}" $((nr+offset)) done echo "" -- cgit v0.10.2 From 61f1e7e20874e8f11dab69b6a4bf7616badd4fe8 Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Fri, 18 Nov 2011 16:25:07 -0800 Subject: x86, syscall: Re-fix typo in comment Fix the same typo as was fixed in: b7641d2c x86-64, syscall: Adjust comment spacing and remove typo ... for the new versions of this file (32-bit and IA32 compat). Signed-off-by: H. Peter Anvin Link: http://lkml.kernel.org/r/1321569446-20433-4-git-send-email-hpa@linux.intel.com diff --git a/arch/x86/ia32/syscall_ia32.c b/arch/x86/ia32/syscall_ia32.c index d04d3db..4754ba0 100644 --- a/arch/x86/ia32/syscall_ia32.c +++ b/arch/x86/ia32/syscall_ia32.c @@ -17,7 +17,7 @@ extern void compat_ni_syscall(void); const sys_call_ptr_t ia32_sys_call_table[__NR_ia32_syscall_max+1] = { /* - * Smells like a like a compiler bug -- it doesn't work + * Smells like a compiler bug -- it doesn't work * when the & below is removed. */ [0 ... __NR_ia32_syscall_max] = &compat_ni_syscall, diff --git a/arch/x86/kernel/syscall_32.c b/arch/x86/kernel/syscall_32.c index b37a573..147fcd4 100644 --- a/arch/x86/kernel/syscall_32.c +++ b/arch/x86/kernel/syscall_32.c @@ -17,7 +17,7 @@ extern asmlinkage void sys_ni_syscall(void); const sys_call_ptr_t sys_call_table[__NR_syscall_max+1] = { /* - * Smells like a like a compiler bug -- it doesn't work + * Smells like a compiler bug -- it doesn't work * when the & below is removed. */ [0 ... __NR_syscall_max] = &sys_ni_syscall, -- cgit v0.10.2 From 3f86886c72fb68088162c7e08cc7f85282f1860c Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Fri, 18 Nov 2011 17:01:19 -0800 Subject: x86, syscall: Allow syscall offset to be symbolic Allow the specified syscall offset to be symbolic, e.g. a macro. For offset system calls, this if nothing else makes the generated code easier to read. Suggested-by: H. J. Lu Link: http://lkml.kernel.org/r/1321569446-20433-7-git-send-email-hpa@linux.intel.com Signed-off-by: H. Peter Anvin diff --git a/arch/x86/syscalls/syscallhdr.sh b/arch/x86/syscalls/syscallhdr.sh index b3c5930..31fd5f1 100644 --- a/arch/x86/syscalls/syscallhdr.sh +++ b/arch/x86/syscalls/syscallhdr.sh @@ -15,7 +15,11 @@ grep -E "^[0-9A-Fa-fXx]+[[:space:]]+${my_abis}" "$in" | sort -n | ( echo "" while read nr abi name entry ; do - echo "#define __NR_${prefix}${name}" $((nr+offset)) + if [ -z "$offset" ]; then + echo "#define __NR_${prefix}${name} $nr" + else + echo "#define __NR_${prefix}${name} ($offset + $nr)" + fi done echo "" -- cgit v0.10.2 From 35621030c0bd5cb4f1a345cf2b4a97e290bc244a Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 23 Sep 2011 13:03:42 -0300 Subject: [media] xc5000: Add support for get_if_frequency This is needed for devices with DRX-K and xc5000. Tested with a HVR 930C hardware. Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/common/tuners/xc5000.c b/drivers/media/common/tuners/xc5000.c index 88b329c..ecd1f95 100644 --- a/drivers/media/common/tuners/xc5000.c +++ b/drivers/media/common/tuners/xc5000.c @@ -968,6 +968,14 @@ static int xc5000_get_frequency(struct dvb_frontend *fe, u32 *freq) return 0; } +static int xc5000_get_if_frequency(struct dvb_frontend *fe, u32 *freq) +{ + struct xc5000_priv *priv = fe->tuner_priv; + dprintk(1, "%s()\n", __func__); + *freq = priv->if_khz * 1000; + return 0; +} + static int xc5000_get_bandwidth(struct dvb_frontend *fe, u32 *bw) { struct xc5000_priv *priv = fe->tuner_priv; @@ -1108,6 +1116,7 @@ static const struct dvb_tuner_ops xc5000_tuner_ops = { .set_params = xc5000_set_params, .set_analog_params = xc5000_set_analog_params, .get_frequency = xc5000_get_frequency, + .get_if_frequency = xc5000_get_if_frequency, .get_bandwidth = xc5000_get_bandwidth, .get_status = xc5000_get_status }; -- cgit v0.10.2 From 82e7dbbd4a16274b0a7038978734fc11bbf9f4b6 Mon Sep 17 00:00:00 2001 From: Eddi De Pieri Date: Sat, 19 Nov 2011 11:37:14 -0300 Subject: [media] em28xx: initial support for HAUPPAUGE HVR-930C again With this patch I try again to add initial support for HVR930C. Tested only DVB-T, since in Italy Analog service is stopped. Actually "scan -a0 -f1", find only about 50 channel while 400 should be available. [mchehab@redhat.com: Tested with DVB-C and fixed a few whitespace issues] Tested-by: Mauro Carvalho Chehab Signed-off-by: Eddi De Pieri Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/common/tuners/xc5000.c b/drivers/media/common/tuners/xc5000.c index ecd1f95..048f489 100644 --- a/drivers/media/common/tuners/xc5000.c +++ b/drivers/media/common/tuners/xc5000.c @@ -1004,6 +1004,8 @@ static int xc_load_fw_and_init_tuner(struct dvb_frontend *fe) struct xc5000_priv *priv = fe->tuner_priv; int ret = 0; + mutex_lock(&xc5000_list_mutex); + if (xc5000_is_firmware_loaded(fe) != XC_RESULT_SUCCESS) { ret = xc5000_fwupload(fe); if (ret != XC_RESULT_SUCCESS) @@ -1023,6 +1025,8 @@ static int xc_load_fw_and_init_tuner(struct dvb_frontend *fe) /* Default to "CABLE" mode */ ret |= xc_write_reg(priv, XREG_SIGNALSOURCE, XC_RF_MODE_CABLE); + mutex_unlock(&xc5000_list_mutex); + return ret; } diff --git a/drivers/media/dvb/frontends/drxk.h b/drivers/media/dvb/frontends/drxk.h index 58baf41..e6d42e2 100644 --- a/drivers/media/dvb/frontends/drxk.h +++ b/drivers/media/dvb/frontends/drxk.h @@ -26,6 +26,8 @@ struct drxk_config { bool antenna_dvbt; u16 antenna_gpio; + int chunk_size; + const char *microcode_name; }; diff --git a/drivers/media/dvb/frontends/drxk_hard.c b/drivers/media/dvb/frontends/drxk_hard.c index dc13fd8..2392092 100644 --- a/drivers/media/dvb/frontends/drxk_hard.c +++ b/drivers/media/dvb/frontends/drxk_hard.c @@ -681,7 +681,8 @@ static int init_state(struct drxk_state *state) state->m_hasOOB = false; state->m_hasAudio = false; - state->m_ChunkSize = 124; + if (!state->m_ChunkSize) + state->m_ChunkSize = 124; state->m_oscClockFreq = 0; state->m_smartAntInverted = false; @@ -6430,6 +6431,7 @@ struct dvb_frontend *drxk_attach(const struct drxk_config *config, state->no_i2c_bridge = config->no_i2c_bridge; state->antenna_gpio = config->antenna_gpio; state->antenna_dvbt = config->antenna_dvbt; + state->m_ChunkSize = config->chunk_size; /* NOTE: as more UIO bits will be used, add them to the mask */ state->UIO_mask = config->antenna_gpio; diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c index 19a5be3..705aedf 100644 --- a/drivers/media/video/em28xx/em28xx-cards.c +++ b/drivers/media/video/em28xx/em28xx-cards.c @@ -336,6 +336,24 @@ static struct em28xx_reg_seq pctv_460e[] = { { -1, -1, -1, -1}, }; +static struct em28xx_reg_seq hauppauge_930c_gpio[] = { +// xc5000 reset + {EM2874_R80_GPIO, 0x6f, 0xff, 10}, + {EM2874_R80_GPIO, 0x4f, 0xff, 10}, + {EM2874_R80_GPIO, 0x6f, 0xff, 10}, + {EM2874_R80_GPIO, 0x4f, 0xff, 10}, + { -1, -1, -1, -1}, +}; + +#if 0 +static struct em28xx_reg_seq hauppauge_930c_digital[] = { + {EM2874_R80_GPIO, 0xf6, 0xff, 10}, + {EM2874_R80_GPIO, 0xe6, 0xff, 100}, + {EM2874_R80_GPIO, 0xa6, 0xff, 10}, + { -1, -1, -1, -1}, +}; +#endif + /* * Board definitions */ @@ -892,6 +910,19 @@ struct em28xx_board em28xx_boards[] = { EM28XX_I2C_CLK_WAIT_ENABLE | EM28XX_I2C_FREQ_400_KHZ, }, + [EM2884_BOARD_HAUPPAUGE_WINTV_HVR_930C] = { + .name = "Hauppauge WinTV HVR 930C", + .has_dvb = 1, +//#if 0 +// .tuner_type = TUNER_XC5000, +// .tuner_addr = 0x41, +// .dvb_gpio = hauppauge_930c_digital, /* FIXME: probably wrong */ + .tuner_gpio = hauppauge_930c_gpio, +//#endif + .i2c_speed = EM2874_I2C_SECONDARY_BUS_SELECT | + EM28XX_I2C_CLK_WAIT_ENABLE | + EM28XX_I2C_FREQ_400_KHZ, + }, [EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900] = { .name = "Hauppauge WinTV HVR 900", .tda9887_conf = TDA9887_PRESENT, @@ -1975,6 +2006,8 @@ struct usb_device_id em28xx_id_table[] = { .driver_info = EM28174_BOARD_PCTV_290E }, { USB_DEVICE(0x2013, 0x024c), .driver_info = EM28174_BOARD_PCTV_460E }, + { USB_DEVICE(0x2040, 0x1605), + .driver_info = EM2884_BOARD_HAUPPAUGE_WINTV_HVR_930C }, { }, }; MODULE_DEVICE_TABLE(usb, em28xx_id_table); @@ -2028,10 +2061,10 @@ int em28xx_tuner_callback(void *ptr, int component, int command, int arg) int rc = 0; struct em28xx *dev = ptr; - if (dev->tuner_type != TUNER_XC2028) + if (dev->tuner_type != TUNER_XC2028 && dev->tuner_type != TUNER_XC5000) return 0; - if (command != XC2028_TUNER_RESET) + if (command != XC2028_TUNER_RESET && command != XC5000_TUNER_RESET) return 0; rc = em28xx_gpio_set(dev, dev->board.tuner_gpio); diff --git a/drivers/media/video/em28xx/em28xx-dvb.c b/drivers/media/video/em28xx/em28xx-dvb.c index cef7a2d..d19939b 100644 --- a/drivers/media/video/em28xx/em28xx-dvb.c +++ b/drivers/media/video/em28xx/em28xx-dvb.c @@ -316,6 +316,14 @@ struct drxk_config terratec_h5_drxk = { .microcode_name = "dvb-usb-terratec-h5-drxk.fw", }; +struct drxk_config hauppauge_930c_drxk = { + .adr = 0x29, + .single_master = 1, + .no_i2c_bridge = 1, + .microcode_name = "dvb-usb-hauppauge-hvr930c-drxk.fw", + .chunk_size = 56, +}; + static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable) { struct em28xx_dvb *dvb = fe->sec_priv; @@ -334,6 +342,90 @@ static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable) return status; } +static void hauppauge_hvr930c_init(struct em28xx *dev) +{ + int i; + + struct em28xx_reg_seq hauppauge_hvr930c_init[] = { + {EM2874_R80_GPIO, 0xff, 0xff, 101}, //11111111 +// {0xd , 0xff, 0xff, 101}, //11111111 + {EM2874_R80_GPIO, 0xfb, 0xff, 50}, //11111011 init bit 3 + {EM2874_R80_GPIO, 0xff, 0xff, 184}, //11111111 + { -1, -1, -1, -1}, + }; + struct em28xx_reg_seq hauppauge_hvr930c_end[] = { + {EM2874_R80_GPIO, 0xef, 0xff, 1}, //11101111 + {EM2874_R80_GPIO, 0xaf, 0xff, 101}, //10101111 init bit 7 + {EM2874_R80_GPIO, 0xef, 0xff, 118}, //11101111 + + +//per il tuner? + {EM2874_R80_GPIO, 0xef, 0xff, 1}, //11101111 + {EM2874_R80_GPIO, 0xcf, 0xff, 11}, //11001111 init bit 6 + {EM2874_R80_GPIO, 0xef, 0xff, 64}, //11101111 + + {EM2874_R80_GPIO, 0xcf, 0xff, 101}, //11001111 init bit 6 + {EM2874_R80_GPIO, 0xef, 0xff, 101}, //11101111 + {EM2874_R80_GPIO, 0xcf, 0xff, 11}, //11001111 init bit 6 + {EM2874_R80_GPIO, 0xef, 0xff, 101}, //11101111 + +// {EM2874_R80_GPIO, 0x6f, 0xff, 10}, //01101111 +// {EM2874_R80_GPIO, 0x6d, 0xff, 100}, //01101101 init bit 2 + { -1, -1, -1, -1}, + }; + + struct em28xx_reg_seq hauppauge_hvr930c_end2[] = { +// {EM2874_R80_GPIO, 0x6f, 0xff, 124}, //01101111 +// {EM2874_R80_GPIO, 0x4f, 0xff, 11}, //01001111 init bit 6 +// {EM2874_R80_GPIO, 0x6f, 0xff, 1}, //01101111 +// {EM2874_R80_GPIO, 0x4f, 0xff, 10}, //01001111 init bit 6 +// {EM2874_R80_GPIO, 0x6f, 0xff, 100}, //01101111 +// {0xd , 0x42, 0xff, 101}, //11111111 + { -1, -1, -1, -1}, + }; + struct { + unsigned char r[4]; + int len; + } regs[] = { + {{ 0x06, 0x02, 0x00, 0x31 }, 4}, + {{ 0x01, 0x02 }, 2}, + {{ 0x01, 0x02, 0x00, 0xc6 }, 4}, + {{ 0x01, 0x00 }, 2}, + {{ 0x01, 0x00, 0xff, 0xaf }, 4}, + {{ 0x01, 0x00, 0x03, 0xa0 }, 4}, + {{ 0x01, 0x00 }, 2}, + {{ 0x01, 0x00, 0x73, 0xaf }, 4}, + {{ 0x04, 0x00 }, 2}, + {{ 0x00, 0x04 }, 2}, + {{ 0x00, 0x04, 0x00, 0x0a }, 4}, + {{ 0x04, 0x14 }, 2}, + {{ 0x04, 0x14, 0x00, 0x00 }, 4}, + }; + + em28xx_gpio_set(dev, hauppauge_hvr930c_init); + em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, 0x40); + msleep(10); + em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, 0x44); + msleep(10); + + dev->i2c_client.addr = 0x82 >> 1; + + for (i = 0; i < ARRAY_SIZE(regs); i++) + i2c_master_send(&dev->i2c_client, regs[i].r, regs[i].len); + em28xx_gpio_set(dev, hauppauge_hvr930c_end); + + msleep(100); + + em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, 0x44); + msleep(30); + + em28xx_gpio_set(dev, hauppauge_hvr930c_end2); + msleep(10); + em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, 0x45); + msleep(10); + +} + static void terratec_h5_init(struct em28xx *dev) { int i; @@ -788,6 +880,47 @@ static int em28xx_dvb_init(struct em28xx *dev) mfe_shared = 1; } break; + case EM2884_BOARD_HAUPPAUGE_WINTV_HVR_930C: + hauppauge_hvr930c_init(dev); + + dvb->dont_attach_fe1 = 1; + + dvb->fe[0] = dvb_attach(drxk_attach, &hauppauge_930c_drxk, &dev->i2c_adap, &dvb->fe[1]); + if (!dvb->fe[0]) { + result = -EINVAL; + goto out_free; + } + /* FIXME: do we need a pll semaphore? */ + dvb->fe[0]->sec_priv = dvb; + sema_init(&dvb->pll_mutex, 1); + dvb->gate_ctrl = dvb->fe[0]->ops.i2c_gate_ctrl; + dvb->fe[0]->ops.i2c_gate_ctrl = drxk_gate_ctrl; + dvb->fe[1]->id = 1; + + /* Attach xc5000 */ + struct xc5000_config cfg; + memset(&cfg, 0, sizeof(cfg)); + cfg.i2c_address = 0x61; + //cfg.if_khz = 4570; //FIXME + cfg.if_khz = 4000; //FIXME (should be ok) read from i2c traffic + + if (dvb->fe[0]->ops.i2c_gate_ctrl) + dvb->fe[0]->ops.i2c_gate_ctrl(dvb->fe[0], 1); + if (!dvb_attach(xc5000_attach, dvb->fe[0], &dev->i2c_adap, &cfg)) { + result = -EINVAL; + goto out_free; + } + + if (dvb->fe[0]->ops.i2c_gate_ctrl) + dvb->fe[0]->ops.i2c_gate_ctrl(dvb->fe[0], 0); + + /* Hack - needed by drxk/tda18271c2dd */ + dvb->fe[1]->tuner_priv = dvb->fe[0]->tuner_priv; + memcpy(&dvb->fe[1]->ops.tuner_ops, + &dvb->fe[0]->ops.tuner_ops, + sizeof(dvb->fe[0]->ops.tuner_ops)); + + break; case EM2884_BOARD_TERRATEC_H5: terratec_h5_init(dev); @@ -798,7 +931,6 @@ static int em28xx_dvb_init(struct em28xx *dev) result = -EINVAL; goto out_free; } - /* FIXME: do we need a pll semaphore? */ dvb->fe[0]->sec_priv = dvb; sema_init(&dvb->pll_mutex, 1); @@ -845,6 +977,8 @@ static int em28xx_dvb_init(struct em28xx *dev) } /* define general-purpose callback pointer */ dvb->fe[0]->callback = em28xx_tuner_callback; + if (dvb->fe[1]) + dvb->fe[1]->callback = em28xx_tuner_callback; /* register everything */ result = em28xx_register_dvb(dvb, THIS_MODULE, dev, &dev->udev->dev); diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h index 2a2cb7e..c16ae8f 100644 --- a/drivers/media/video/em28xx/em28xx.h +++ b/drivers/media/video/em28xx/em28xx.h @@ -38,6 +38,7 @@ #include #endif #include "tuner-xc2028.h" +#include "xc5000.h" #include "em28xx-reg.h" /* Boards supported by driver */ @@ -121,6 +122,7 @@ #define EM28174_BOARD_PCTV_290E 78 #define EM2884_BOARD_TERRATEC_H5 79 #define EM28174_BOARD_PCTV_460E 80 +#define EM2884_BOARD_HAUPPAUGE_WINTV_HVR_930C 81 /* Limits minimum and default number of buffers */ #define EM28XX_MIN_BUF 4 -- cgit v0.10.2 From de72405f6fc1aaedc0412f88cf681ed33519c49a Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 20 Nov 2011 11:23:24 -0200 Subject: [media] em28xx: Fix CodingStyle issues introduced by changeset 82e7dbb Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/dvb/frontends/drxk_hard.c b/drivers/media/dvb/frontends/drxk_hard.c index 2392092..95cbc98 100644 --- a/drivers/media/dvb/frontends/drxk_hard.c +++ b/drivers/media/dvb/frontends/drxk_hard.c @@ -682,7 +682,7 @@ static int init_state(struct drxk_state *state) state->m_hasAudio = false; if (!state->m_ChunkSize) - state->m_ChunkSize = 124; + state->m_ChunkSize = 124; state->m_oscClockFreq = 0; state->m_smartAntInverted = false; diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c index 705aedf..d92e0af 100644 --- a/drivers/media/video/em28xx/em28xx-cards.c +++ b/drivers/media/video/em28xx/em28xx-cards.c @@ -337,9 +337,8 @@ static struct em28xx_reg_seq pctv_460e[] = { }; static struct em28xx_reg_seq hauppauge_930c_gpio[] = { -// xc5000 reset {EM2874_R80_GPIO, 0x6f, 0xff, 10}, - {EM2874_R80_GPIO, 0x4f, 0xff, 10}, + {EM2874_R80_GPIO, 0x4f, 0xff, 10}, /* xc5000 reset */ {EM2874_R80_GPIO, 0x6f, 0xff, 10}, {EM2874_R80_GPIO, 0x4f, 0xff, 10}, { -1, -1, -1, -1}, @@ -905,6 +904,8 @@ struct em28xx_board em28xx_boards[] = { .tuner_addr = 0x41, .dvb_gpio = terratec_h5_digital, /* FIXME: probably wrong */ .tuner_gpio = terratec_h5_gpio, +#else + .tuner_type = TUNER_ABSENT, #endif .i2c_speed = EM2874_I2C_SECONDARY_BUS_SELECT | EM28XX_I2C_CLK_WAIT_ENABLE | @@ -913,12 +914,14 @@ struct em28xx_board em28xx_boards[] = { [EM2884_BOARD_HAUPPAUGE_WINTV_HVR_930C] = { .name = "Hauppauge WinTV HVR 930C", .has_dvb = 1, -//#if 0 -// .tuner_type = TUNER_XC5000, -// .tuner_addr = 0x41, -// .dvb_gpio = hauppauge_930c_digital, /* FIXME: probably wrong */ +#if 0 /* FIXME: Add analog support */ + .tuner_type = TUNER_XC5000, + .tuner_addr = 0x41, + .dvb_gpio = hauppauge_930c_digital, .tuner_gpio = hauppauge_930c_gpio, -//#endif +#else + .tuner_type = TUNER_ABSENT, +#endif .i2c_speed = EM2874_I2C_SECONDARY_BUS_SELECT | EM28XX_I2C_CLK_WAIT_ENABLE | EM28XX_I2C_FREQ_400_KHZ, diff --git a/drivers/media/video/em28xx/em28xx-dvb.c b/drivers/media/video/em28xx/em28xx-dvb.c index d19939b..55a9008 100644 --- a/drivers/media/video/em28xx/em28xx-dvb.c +++ b/drivers/media/video/em28xx/em28xx-dvb.c @@ -347,42 +347,27 @@ static void hauppauge_hvr930c_init(struct em28xx *dev) int i; struct em28xx_reg_seq hauppauge_hvr930c_init[] = { - {EM2874_R80_GPIO, 0xff, 0xff, 101}, //11111111 -// {0xd , 0xff, 0xff, 101}, //11111111 - {EM2874_R80_GPIO, 0xfb, 0xff, 50}, //11111011 init bit 3 - {EM2874_R80_GPIO, 0xff, 0xff, 184}, //11111111 + {EM2874_R80_GPIO, 0xff, 0xff, 0x65}, + {EM2874_R80_GPIO, 0xfb, 0xff, 0x32}, + {EM2874_R80_GPIO, 0xff, 0xff, 0xb8}, { -1, -1, -1, -1}, }; struct em28xx_reg_seq hauppauge_hvr930c_end[] = { - {EM2874_R80_GPIO, 0xef, 0xff, 1}, //11101111 - {EM2874_R80_GPIO, 0xaf, 0xff, 101}, //10101111 init bit 7 - {EM2874_R80_GPIO, 0xef, 0xff, 118}, //11101111 + {EM2874_R80_GPIO, 0xef, 0xff, 0x01}, + {EM2874_R80_GPIO, 0xaf, 0xff, 0x65}, + {EM2874_R80_GPIO, 0xef, 0xff, 0x76}, + {EM2874_R80_GPIO, 0xef, 0xff, 0x01}, + {EM2874_R80_GPIO, 0xcf, 0xff, 0x0b}, + {EM2874_R80_GPIO, 0xef, 0xff, 0x40}, + + {EM2874_R80_GPIO, 0xcf, 0xff, 0x65}, + {EM2874_R80_GPIO, 0xef, 0xff, 0x65}, + {EM2874_R80_GPIO, 0xcf, 0xff, 0x0b}, + {EM2874_R80_GPIO, 0xef, 0xff, 0x65}, - -//per il tuner? - {EM2874_R80_GPIO, 0xef, 0xff, 1}, //11101111 - {EM2874_R80_GPIO, 0xcf, 0xff, 11}, //11001111 init bit 6 - {EM2874_R80_GPIO, 0xef, 0xff, 64}, //11101111 - - {EM2874_R80_GPIO, 0xcf, 0xff, 101}, //11001111 init bit 6 - {EM2874_R80_GPIO, 0xef, 0xff, 101}, //11101111 - {EM2874_R80_GPIO, 0xcf, 0xff, 11}, //11001111 init bit 6 - {EM2874_R80_GPIO, 0xef, 0xff, 101}, //11101111 - -// {EM2874_R80_GPIO, 0x6f, 0xff, 10}, //01101111 -// {EM2874_R80_GPIO, 0x6d, 0xff, 100}, //01101101 init bit 2 { -1, -1, -1, -1}, }; - struct em28xx_reg_seq hauppauge_hvr930c_end2[] = { -// {EM2874_R80_GPIO, 0x6f, 0xff, 124}, //01101111 -// {EM2874_R80_GPIO, 0x4f, 0xff, 11}, //01001111 init bit 6 -// {EM2874_R80_GPIO, 0x6f, 0xff, 1}, //01101111 -// {EM2874_R80_GPIO, 0x4f, 0xff, 10}, //01001111 init bit 6 -// {EM2874_R80_GPIO, 0x6f, 0xff, 100}, //01101111 -// {0xd , 0x42, 0xff, 101}, //11111111 - { -1, -1, -1, -1}, - }; struct { unsigned char r[4]; int len; @@ -419,8 +404,6 @@ static void hauppauge_hvr930c_init(struct em28xx *dev) em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, 0x44); msleep(30); - em28xx_gpio_set(dev, hauppauge_hvr930c_end2); - msleep(10); em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, 0x45); msleep(10); @@ -885,7 +868,9 @@ static int em28xx_dvb_init(struct em28xx *dev) dvb->dont_attach_fe1 = 1; - dvb->fe[0] = dvb_attach(drxk_attach, &hauppauge_930c_drxk, &dev->i2c_adap, &dvb->fe[1]); + dvb->fe[0] = dvb_attach(drxk_attach, + &hauppauge_930c_drxk, &dev->i2c_adap, + &dvb->fe[1]); if (!dvb->fe[0]) { result = -EINVAL; goto out_free; @@ -901,12 +886,12 @@ static int em28xx_dvb_init(struct em28xx *dev) struct xc5000_config cfg; memset(&cfg, 0, sizeof(cfg)); cfg.i2c_address = 0x61; - //cfg.if_khz = 4570; //FIXME - cfg.if_khz = 4000; //FIXME (should be ok) read from i2c traffic + cfg.if_khz = 4000; if (dvb->fe[0]->ops.i2c_gate_ctrl) dvb->fe[0]->ops.i2c_gate_ctrl(dvb->fe[0], 1); - if (!dvb_attach(xc5000_attach, dvb->fe[0], &dev->i2c_adap, &cfg)) { + if (!dvb_attach(xc5000_attach, dvb->fe[0], &dev->i2c_adap, + &cfg)) { result = -EINVAL; goto out_free; } @@ -978,7 +963,7 @@ static int em28xx_dvb_init(struct em28xx *dev) /* define general-purpose callback pointer */ dvb->fe[0]->callback = em28xx_tuner_callback; if (dvb->fe[1]) - dvb->fe[1]->callback = em28xx_tuner_callback; + dvb->fe[1]->callback = em28xx_tuner_callback; /* register everything */ result = em28xx_register_dvb(dvb, THIS_MODULE, dev, &dev->udev->dev); -- cgit v0.10.2 From 20ae9742eba1bbd1f9d6658d1a1a72bc77fc741d Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 20 Nov 2011 12:23:54 -0200 Subject: [media] em28xx: Add IR support for em2884 Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/em28xx/em28xx-input.c b/drivers/media/video/em28xx/em28xx-input.c index 679da48..2630b26 100644 --- a/drivers/media/video/em28xx/em28xx-input.c +++ b/drivers/media/video/em28xx/em28xx-input.c @@ -306,7 +306,8 @@ static void em28xx_ir_handle_key(struct em28xx_IR *ir) poll_result.rc_data[0], poll_result.toggle_bit); - if (ir->dev->chip_id == CHIP_ID_EM2874) + if (ir->dev->chip_id == CHIP_ID_EM2874 || + ir->dev->chip_id == CHIP_ID_EM2884) /* The em2874 clears the readcount field every time the register is read. The em2860/2880 datasheet says that it is supposed to clear the readcount, but it doesn't. So with @@ -371,13 +372,15 @@ int em28xx_ir_change_protocol(struct rc_dev *rc_dev, u64 rc_type) case CHIP_ID_EM2883: ir->get_key = default_polling_getkey; break; + case CHIP_ID_EM2884: case CHIP_ID_EM2874: case CHIP_ID_EM28174: ir->get_key = em2874_polling_getkey; em28xx_write_regs(dev, EM2874_R50_IR_CONFIG, &ir_config, 1); break; default: - printk("Unrecognized em28xx chip id: IR not supported\n"); + printk("Unrecognized em28xx chip id 0x%02x: IR not supported\n", + dev->chip_id); rc = -EINVAL; } -- cgit v0.10.2 From dfbbf5da6c2266580df8b8aab0b43595bed55e48 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 20 Nov 2011 12:16:25 -0200 Subject: [media] em28xx: Add IR support for HVR-930C Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/rc/keymaps/rc-hauppauge.c b/drivers/media/rc/keymaps/rc-hauppauge.c index cd3db77..0afb23b 100644 --- a/drivers/media/rc/keymaps/rc-hauppauge.c +++ b/drivers/media/rc/keymaps/rc-hauppauge.c @@ -182,6 +182,57 @@ static struct rc_map_table rc5_hauppauge_new[] = { { 0x1d3f, KEY_HOME }, /* + * Keycodes for PT# R-005 remote bundled with Haupauge HVR-930C + * Keycodes start with address = 0x1c + */ + { 0x1c3b, KEY_GOTO }, + { 0x1c3d, KEY_POWER }, + + { 0x1c14, KEY_UP }, + { 0x1c15, KEY_DOWN }, + { 0x1c16, KEY_LEFT }, + { 0x1c17, KEY_RIGHT }, + { 0x1c25, KEY_OK }, + + { 0x1c00, KEY_0 }, + { 0x1c01, KEY_1 }, + { 0x1c02, KEY_2 }, + { 0x1c03, KEY_3 }, + { 0x1c04, KEY_4 }, + { 0x1c05, KEY_5 }, + { 0x1c06, KEY_6 }, + { 0x1c07, KEY_7 }, + { 0x1c08, KEY_8 }, + { 0x1c09, KEY_9 }, + + { 0x1c1f, KEY_EXIT }, /* BACK */ + { 0x1c0d, KEY_MENU }, + { 0x1c1c, KEY_TV }, + + { 0x1c10, KEY_VOLUMEUP }, + { 0x1c11, KEY_VOLUMEDOWN }, + + { 0x1c20, KEY_CHANNELUP }, + { 0x1c21, KEY_CHANNELDOWN }, + + { 0x1c0f, KEY_MUTE }, + { 0x1c12, KEY_PREVIOUS }, /* Prev */ + + { 0x1c36, KEY_STOP }, + { 0x1c37, KEY_RECORD }, + + { 0x1c24, KEY_LAST }, /* <| */ + { 0x1c1e, KEY_NEXT }, /* >| */ + + { 0x1c0a, KEY_TEXT }, + { 0x1c0e, KEY_SUBTITLE }, /* CC */ + + { 0x1c32, KEY_REWIND }, + { 0x1c30, KEY_PAUSE }, + { 0x1c35, KEY_PLAY }, + { 0x1c34, KEY_FASTFORWARD }, + + /* * Keycodes for the old Black Remote Controller * This one also uses RC-5 protocol * Keycodes start with address = 0x00 diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c index d92e0af..f63a715 100644 --- a/drivers/media/video/em28xx/em28xx-cards.c +++ b/drivers/media/video/em28xx/em28xx-cards.c @@ -922,6 +922,7 @@ struct em28xx_board em28xx_boards[] = { #else .tuner_type = TUNER_ABSENT, #endif + .ir_codes = RC_MAP_HAUPPAUGE, .i2c_speed = EM2874_I2C_SECONDARY_BUS_SELECT | EM28XX_I2C_CLK_WAIT_ENABLE | EM28XX_I2C_FREQ_400_KHZ, -- cgit v0.10.2 From 6fd7dba026f17076ac4bd63a3590f993c1f5c2c6 Mon Sep 17 00:00:00 2001 From: Eddi De Pieri Date: Mon, 21 Nov 2011 06:43:52 -0300 Subject: [media] get_dvb_firmware: add support for HVR-930C firmware Signed-off-by: Eddi De Pieri Signed-off-by: Mauro Carvalho Chehab diff --git a/Documentation/dvb/get_dvb_firmware b/Documentation/dvb/get_dvb_firmware index e67be7a..0f15ab7 100755 --- a/Documentation/dvb/get_dvb_firmware +++ b/Documentation/dvb/get_dvb_firmware @@ -27,8 +27,8 @@ use IO::Handle; "or51211", "or51132_qam", "or51132_vsb", "bluebird", "opera1", "cx231xx", "cx18", "cx23885", "pvrusb2", "mpc718", "af9015", "ngene", "az6027", "lme2510_lg", "lme2510c_s7395", - "lme2510c_s7395_old", "drxk", "drxk_terratec_h5", "tda10071", - "it9135" ); + "lme2510c_s7395_old", "drxk", "drxk_terratec_h5", + "drxk_hauppauge_hvr930c", "tda10071", "it9135" ); # Check args syntax() if (scalar(@ARGV) != 1); @@ -644,6 +644,24 @@ sub drxk { "$fwfile" } +sub drxk_hauppauge_hvr930c { + my $url = "http://www.wintvcd.co.uk/drivers/"; + my $zipfile = "HVR-9x0_5_10_325_28153_SIGNED.zip"; + my $hash = "83ab82e7e9480ec8bf1ae0155ca63c88"; + my $tmpdir = tempdir(DIR => "/tmp", CLEANUP => 1); + my $drvfile = "HVR-900/emOEM.sys"; + my $fwfile = "dvb-usb-hauppauge-hvr930c-drxk.fw"; + + checkstandard(); + + wgetfile($zipfile, $url . $zipfile); + verify($zipfile, $hash); + unzip($zipfile, $tmpdir); + extract("$tmpdir/$drvfile", 0x117b0, 42692, "$fwfile"); + + "$fwfile" +} + sub drxk_terratec_h5 { my $url = "http://www.linuxtv.org/downloads/firmware/"; my $hash = "19000dada8e2741162ccc50cc91fa7f1"; -- cgit v0.10.2 From 41e583c22c3f907e46e329764b4606117040a1ae Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Tue, 8 Nov 2011 20:33:29 -0800 Subject: fbdev: sh_mobile_lcdcfb: fixup LDHAJR :: HSYNPAJ needs mask LDHAJR register will be broken by hsync_pos without this patch Signed-off-by: Kuninori Morimoto Acked-by: Magnus Damm Signed-off-by: Florian Tobias Schandinat diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c index facffc2..1f49ab4 100644 --- a/drivers/video/sh_mobile_lcdcfb.c +++ b/drivers/video/sh_mobile_lcdcfb.c @@ -420,7 +420,7 @@ static void sh_mobile_lcdc_geometry(struct sh_mobile_lcdc_chan *ch) tmp = ((display_var->xres & 7) << 24) | ((display_h_total & 7) << 16) | ((display_var->hsync_len & 7) << 8) | - hsync_pos; + (hsync_pos & 7); lcdc_write_chan(ch, LDHAJR, tmp); } -- cgit v0.10.2 From 9250741e5feedb6a5273683a940b339af59a1086 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Tue, 8 Nov 2011 20:33:47 -0800 Subject: fbdev: sh_mipi_dsi: tidyup dsip_clk dsipck clock is controled by CLKDEV_ICK_ID() in clock-shxxx. dsi0p_clk/dsi1p_clk naming is not needed. Signed-off-by: Kuninori Morimoto Acked-by: Magnus Damm Signed-off-by: Florian Tobias Schandinat diff --git a/arch/arm/mach-shmobile/clock-sh7372.c b/arch/arm/mach-shmobile/clock-sh7372.c index 995a9c3..1ebab17 100644 --- a/arch/arm/mach-shmobile/clock-sh7372.c +++ b/arch/arm/mach-shmobile/clock-sh7372.c @@ -612,8 +612,8 @@ static struct clk_lookup lookups[] = { CLKDEV_CON_ID("hdmi_clk", &div6_reparent_clks[DIV6_HDMI]), CLKDEV_ICK_ID("dsit_clk", "sh-mipi-dsi.0", &div6_clks[DIV6_DSIT]), CLKDEV_ICK_ID("dsit_clk", "sh-mipi-dsi.1", &div6_clks[DIV6_DSIT]), - CLKDEV_ICK_ID("dsi0p_clk", "sh-mipi-dsi.0", &div6_clks[DIV6_DSI0P]), - CLKDEV_ICK_ID("dsi1p_clk", "sh-mipi-dsi.1", &div6_clks[DIV6_DSI1P]), + CLKDEV_ICK_ID("dsip_clk", "sh-mipi-dsi.0", &div6_clks[DIV6_DSI0P]), + CLKDEV_ICK_ID("dsip_clk", "sh-mipi-dsi.1", &div6_clks[DIV6_DSI1P]), /* MSTP32 clocks */ CLKDEV_DEV_ID("i2c-sh_mobile.2", &mstp_clks[MSTP001]), /* IIC2 */ diff --git a/arch/arm/mach-shmobile/clock-sh73a0.c b/arch/arm/mach-shmobile/clock-sh73a0.c index 61a846b..3da30ba 100644 --- a/arch/arm/mach-shmobile/clock-sh73a0.c +++ b/arch/arm/mach-shmobile/clock-sh73a0.c @@ -319,8 +319,8 @@ static struct clk_lookup lookups[] = { CLKDEV_CON_ID("sdhi2_clk", &div6_clks[DIV6_SDHI2]), CLKDEV_ICK_ID("dsit_clk", "sh-mipi-dsi.0", &div6_clks[DIV6_DSIT]), CLKDEV_ICK_ID("dsit_clk", "sh-mipi-dsi.1", &div6_clks[DIV6_DSIT]), - CLKDEV_ICK_ID("dsi0p_clk", "sh-mipi-dsi.0", &div6_clks[DIV6_DSI0P]), - CLKDEV_ICK_ID("dsi1p_clk", "sh-mipi-dsi.1", &div6_clks[DIV6_DSI1P]), + CLKDEV_ICK_ID("dsip_clk", "sh-mipi-dsi.0", &div6_clks[DIV6_DSI0P]), + CLKDEV_ICK_ID("dsip_clk", "sh-mipi-dsi.1", &div6_clks[DIV6_DSI1P]), /* MSTP32 clocks */ CLKDEV_DEV_ID("i2c-sh_mobile.2", &mstp_clks[MSTP001]), /* I2C2 */ diff --git a/drivers/video/sh_mipi_dsi.c b/drivers/video/sh_mipi_dsi.c index 72ee96b..4aa5053 100644 --- a/drivers/video/sh_mipi_dsi.c +++ b/drivers/video/sh_mipi_dsi.c @@ -363,7 +363,6 @@ static int __init sh_mipi_probe(struct platform_device *pdev) struct resource *res2 = platform_get_resource(pdev, IORESOURCE_MEM, 1); unsigned long rate, f_current; int idx = pdev->id, ret; - char dsip_clk[] = "dsi.p_clk"; if (!res || !res2 || idx >= ARRAY_SIZE(mipi_dsi) || !pdata) return -ENODEV; @@ -428,8 +427,7 @@ static int __init sh_mipi_probe(struct platform_device *pdev) dev_dbg(&pdev->dev, "DSI-T clk %lu -> %lu\n", f_current, rate); - sprintf(dsip_clk, "dsi%1.1dp_clk", idx); - mipi->dsip_clk = clk_get(&pdev->dev, dsip_clk); + mipi->dsip_clk = clk_get(&pdev->dev, "dsip_clk"); if (IS_ERR(mipi->dsip_clk)) { ret = PTR_ERR(mipi->dsip_clk); goto eclkpget; -- cgit v0.10.2 From 32ba95c69f33126e297466dc706db73cc7e7a543 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Tue, 8 Nov 2011 20:34:01 -0800 Subject: fbdev: sh_mipi_dsi: typo fix of SH_MIPI_DSI_HBPBM Signed-off-by: Kuninori Morimoto Acked-by: Magnus Damm Signed-off-by: Florian Tobias Schandinat diff --git a/drivers/video/sh_mipi_dsi.c b/drivers/video/sh_mipi_dsi.c index 4aa5053..94bb1bb 100644 --- a/drivers/video/sh_mipi_dsi.c +++ b/drivers/video/sh_mipi_dsi.c @@ -318,7 +318,7 @@ static int __init sh_mipi_setup(struct sh_mipi *mipi, */ if (pdata->flags & SH_MIPI_DSI_HSABM) vmctr2 |= 0x20; - if (pdata->flags & SH_MIPI_DSI_HSPBM) + if (pdata->flags & SH_MIPI_DSI_HBPBM) vmctr2 |= 0x10; iowrite32(vmctr2, mipi->linkbase + VMCTR2); diff --git a/include/video/sh_mipi_dsi.h b/include/video/sh_mipi_dsi.h index 6cb95c9..4e2bcb5 100644 --- a/include/video/sh_mipi_dsi.h +++ b/include/video/sh_mipi_dsi.h @@ -28,7 +28,7 @@ enum sh_mipi_dsi_data_fmt { struct sh_mobile_lcdc_chan_cfg; #define SH_MIPI_DSI_HSABM (1 << 0) -#define SH_MIPI_DSI_HSPBM (1 << 1) +#define SH_MIPI_DSI_HBPBM (1 << 1) struct sh_mipi_dsi_info { enum sh_mipi_dsi_data_fmt data_format; -- cgit v0.10.2 From 3c2a659936ba1e3bbd7e5eca89255c134fafb506 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Tue, 8 Nov 2011 20:34:12 -0800 Subject: fbdev: sh_mipi_dsi: tidyup VMCTR2 parameter expression VMCTR2 parameter will be supported more in the future. 1 << xx style is easy to understand. Signed-off-by: Kuninori Morimoto Acked-by: Magnus Damm Signed-off-by: Florian Tobias Schandinat diff --git a/drivers/video/sh_mipi_dsi.c b/drivers/video/sh_mipi_dsi.c index 94bb1bb..20ccc23 100644 --- a/drivers/video/sh_mipi_dsi.c +++ b/drivers/video/sh_mipi_dsi.c @@ -317,9 +317,9 @@ static int __init sh_mipi_setup(struct sh_mipi *mipi, * HSA period allowed, no commands in LP */ if (pdata->flags & SH_MIPI_DSI_HSABM) - vmctr2 |= 0x20; + vmctr2 |= 1 << 5; if (pdata->flags & SH_MIPI_DSI_HBPBM) - vmctr2 |= 0x10; + vmctr2 |= 1 << 4; iowrite32(vmctr2, mipi->linkbase + VMCTR2); /* -- cgit v0.10.2 From f7b0af68bc9f5eb5291996706951661d57909137 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Tue, 8 Nov 2011 20:34:24 -0800 Subject: fbdev: sh_mipi_dsi: add SH_MIPI_DSI_HFPBM flag Signed-off-by: Kuninori Morimoto Acked-by: Magnus Damm Signed-off-by: Florian Tobias Schandinat diff --git a/drivers/video/sh_mipi_dsi.c b/drivers/video/sh_mipi_dsi.c index 20ccc23..c9fac13 100644 --- a/drivers/video/sh_mipi_dsi.c +++ b/drivers/video/sh_mipi_dsi.c @@ -320,6 +320,8 @@ static int __init sh_mipi_setup(struct sh_mipi *mipi, vmctr2 |= 1 << 5; if (pdata->flags & SH_MIPI_DSI_HBPBM) vmctr2 |= 1 << 4; + if (pdata->flags & SH_MIPI_DSI_HFPBM) + vmctr2 |= 1 << 3; iowrite32(vmctr2, mipi->linkbase + VMCTR2); /* diff --git a/include/video/sh_mipi_dsi.h b/include/video/sh_mipi_dsi.h index 4e2bcb5..86a72c0 100644 --- a/include/video/sh_mipi_dsi.h +++ b/include/video/sh_mipi_dsi.h @@ -29,6 +29,7 @@ struct sh_mobile_lcdc_chan_cfg; #define SH_MIPI_DSI_HSABM (1 << 0) #define SH_MIPI_DSI_HBPBM (1 << 1) +#define SH_MIPI_DSI_HFPBM (1 << 2) struct sh_mipi_dsi_info { enum sh_mipi_dsi_data_fmt data_format; -- cgit v0.10.2 From d07a9d2a5e82ed677971b2e9f3e4cbd49b9ec34e Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Tue, 8 Nov 2011 20:34:33 -0800 Subject: fbdev: sh_mipi_dsi: add SH_MIPI_DSI_BL2E flag Signed-off-by: Kuninori Morimoto Acked-by: Magnus Damm Signed-off-by: Florian Tobias Schandinat diff --git a/drivers/video/sh_mipi_dsi.c b/drivers/video/sh_mipi_dsi.c index c9fac13..dfd5154 100644 --- a/drivers/video/sh_mipi_dsi.c +++ b/drivers/video/sh_mipi_dsi.c @@ -316,6 +316,8 @@ static int __init sh_mipi_setup(struct sh_mipi *mipi, * Non-burst mode with sync pulses: VSE and HSE are output, * HSA period allowed, no commands in LP */ + if (pdata->flags & SH_MIPI_DSI_BL2E) + vmctr2 |= 1 << 17; if (pdata->flags & SH_MIPI_DSI_HSABM) vmctr2 |= 1 << 5; if (pdata->flags & SH_MIPI_DSI_HBPBM) diff --git a/include/video/sh_mipi_dsi.h b/include/video/sh_mipi_dsi.h index 86a72c0..58b78f8 100644 --- a/include/video/sh_mipi_dsi.h +++ b/include/video/sh_mipi_dsi.h @@ -30,6 +30,7 @@ struct sh_mobile_lcdc_chan_cfg; #define SH_MIPI_DSI_HSABM (1 << 0) #define SH_MIPI_DSI_HBPBM (1 << 1) #define SH_MIPI_DSI_HFPBM (1 << 2) +#define SH_MIPI_DSI_BL2E (1 << 3) struct sh_mipi_dsi_info { enum sh_mipi_dsi_data_fmt data_format; -- cgit v0.10.2 From 26c3d7ac219e74ab3939048a32d6bd3b4a16798a Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Tue, 8 Nov 2011 20:34:43 -0800 Subject: fbdev: sh_mipi_dsi: add lane control support SH MIPI DSI can use 0-4 lane Signed-off-by: Kuninori Morimoto Acked-by: Magnus Damm Signed-off-by: Florian Tobias Schandinat diff --git a/arch/arm/mach-shmobile/board-ag5evm.c b/arch/arm/mach-shmobile/board-ag5evm.c index b862e9f..e969fe9 100644 --- a/arch/arm/mach-shmobile/board-ag5evm.c +++ b/arch/arm/mach-shmobile/board-ag5evm.c @@ -324,6 +324,7 @@ static struct resource mipidsi0_resources[] = { static struct sh_mipi_dsi_info mipidsi0_info = { .data_format = MIPI_RGB888, .lcd_chan = &lcdc0_info.ch[0], + .lane = 2, .vsynw_offset = 20, .clksrc = 1, .flags = SH_MIPI_DSI_HSABM, diff --git a/arch/arm/mach-shmobile/board-ap4evb.c b/arch/arm/mach-shmobile/board-ap4evb.c index 4c865ec..b7d006f 100644 --- a/arch/arm/mach-shmobile/board-ap4evb.c +++ b/arch/arm/mach-shmobile/board-ap4evb.c @@ -580,6 +580,7 @@ static struct resource mipidsi0_resources[] = { static struct sh_mipi_dsi_info mipidsi0_info = { .data_format = MIPI_RGB888, .lcd_chan = &lcdc_info.ch[0], + .lane = 2, .vsynw_offset = 17, }; diff --git a/drivers/video/sh_mipi_dsi.c b/drivers/video/sh_mipi_dsi.c index dfd5154..af6bec2 100644 --- a/drivers/video/sh_mipi_dsi.c +++ b/drivers/video/sh_mipi_dsi.c @@ -8,6 +8,7 @@ * published by the Free Software Foundation. */ +#include #include #include #include @@ -153,6 +154,7 @@ static int __init sh_mipi_setup(struct sh_mipi *mipi, struct sh_mobile_lcdc_chan_cfg *ch = pdata->lcd_chan; u32 pctype, datatype, pixfmt, linelength, vmctr2 = 0x00e00000; bool yuv; + u32 tmp; /* * Select data format. MIPI DSI is not hot-pluggable, so, we just use @@ -253,6 +255,9 @@ static int __init sh_mipi_setup(struct sh_mipi *mipi, (!yuv && ch->interface_type != RGB24)) return -EINVAL; + if (!pdata->lane) + return -EINVAL; + /* reset DSI link */ iowrite32(0x00000001, base + SYSCTRL); /* Hold reset for 100 cycles of the slowest of bus, HS byte and LP clock */ @@ -269,7 +274,10 @@ static int __init sh_mipi_setup(struct sh_mipi *mipi, * ECC check enable * additionally enable first two lanes */ - iowrite32(0x00003703, base + SYSCONF); + bitmap_fill((unsigned long *)&tmp, pdata->lane); + tmp |= 0x00003700; + iowrite32(tmp, base + SYSCONF); + /* * T_wakeup = 0x7000 * T_hs-trail = 3 diff --git a/include/video/sh_mipi_dsi.h b/include/video/sh_mipi_dsi.h index 58b78f8..3d0ec50 100644 --- a/include/video/sh_mipi_dsi.h +++ b/include/video/sh_mipi_dsi.h @@ -35,6 +35,7 @@ struct sh_mobile_lcdc_chan_cfg; struct sh_mipi_dsi_info { enum sh_mipi_dsi_data_fmt data_format; struct sh_mobile_lcdc_chan_cfg *lcd_chan; + int lane; unsigned long flags; u32 clksrc; unsigned int vsynw_offset; -- cgit v0.10.2 From f832906a56bcf9c597589e9a7898c1dd2f0513b9 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Tue, 8 Nov 2011 20:34:55 -0800 Subject: fbdev: sh_mipi_dsi: add sync_pulses/sync_events/burst mode Signed-off-by: Kuninori Morimoto Acked-by: Magnus Damm Signed-off-by: Florian Tobias Schandinat diff --git a/arch/arm/mach-shmobile/board-ag5evm.c b/arch/arm/mach-shmobile/board-ag5evm.c index e969fe9..6993844 100644 --- a/arch/arm/mach-shmobile/board-ag5evm.c +++ b/arch/arm/mach-shmobile/board-ag5evm.c @@ -327,7 +327,8 @@ static struct sh_mipi_dsi_info mipidsi0_info = { .lane = 2, .vsynw_offset = 20, .clksrc = 1, - .flags = SH_MIPI_DSI_HSABM, + .flags = SH_MIPI_DSI_HSABM | + SH_MIPI_DSI_SYNC_PULSES_MODE, }; static struct platform_device mipidsi0_device = { diff --git a/arch/arm/mach-shmobile/board-ap4evb.c b/arch/arm/mach-shmobile/board-ap4evb.c index b7d006f..b2e32c8 100644 --- a/arch/arm/mach-shmobile/board-ap4evb.c +++ b/arch/arm/mach-shmobile/board-ap4evb.c @@ -582,6 +582,7 @@ static struct sh_mipi_dsi_info mipidsi0_info = { .lcd_chan = &lcdc_info.ch[0], .lane = 2, .vsynw_offset = 17, + .flags = SH_MIPI_DSI_SYNC_PULSES_MODE, }; static struct platform_device mipidsi0_device = { diff --git a/drivers/video/sh_mipi_dsi.c b/drivers/video/sh_mipi_dsi.c index af6bec2..b8c4873 100644 --- a/drivers/video/sh_mipi_dsi.c +++ b/drivers/video/sh_mipi_dsi.c @@ -152,7 +152,7 @@ static int __init sh_mipi_setup(struct sh_mipi *mipi, { void __iomem *base = mipi->base; struct sh_mobile_lcdc_chan_cfg *ch = pdata->lcd_chan; - u32 pctype, datatype, pixfmt, linelength, vmctr2 = 0x00e00000; + u32 pctype, datatype, pixfmt, linelength, vmctr2; bool yuv; u32 tmp; @@ -324,6 +324,13 @@ static int __init sh_mipi_setup(struct sh_mipi *mipi, * Non-burst mode with sync pulses: VSE and HSE are output, * HSA period allowed, no commands in LP */ + vmctr2 = 0; + if (pdata->flags & SH_MIPI_DSI_VSEE) + vmctr2 |= 1 << 23; + if (pdata->flags & SH_MIPI_DSI_HSEE) + vmctr2 |= 1 << 22; + if (pdata->flags & SH_MIPI_DSI_HSAE) + vmctr2 |= 1 << 21; if (pdata->flags & SH_MIPI_DSI_BL2E) vmctr2 |= 1 << 17; if (pdata->flags & SH_MIPI_DSI_HSABM) diff --git a/include/video/sh_mipi_dsi.h b/include/video/sh_mipi_dsi.h index 3d0ec50..c8225b4 100644 --- a/include/video/sh_mipi_dsi.h +++ b/include/video/sh_mipi_dsi.h @@ -31,6 +31,15 @@ struct sh_mobile_lcdc_chan_cfg; #define SH_MIPI_DSI_HBPBM (1 << 1) #define SH_MIPI_DSI_HFPBM (1 << 2) #define SH_MIPI_DSI_BL2E (1 << 3) +#define SH_MIPI_DSI_VSEE (1 << 4) +#define SH_MIPI_DSI_HSEE (1 << 5) +#define SH_MIPI_DSI_HSAE (1 << 6) + +#define SH_MIPI_DSI_SYNC_PULSES_MODE (SH_MIPI_DSI_VSEE | \ + SH_MIPI_DSI_HSEE | \ + SH_MIPI_DSI_HSAE) +#define SH_MIPI_DSI_SYNC_EVENTS_MODE (0) +#define SH_MIPI_DSI_SYNC_BURST_MODE (SH_MIPI_DSI_BL2E) struct sh_mipi_dsi_info { enum sh_mipi_dsi_data_fmt data_format; -- cgit v0.10.2 From 08750617badd03fd95f33921a5213a5632022178 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Tue, 8 Nov 2011 20:35:05 -0800 Subject: fbdev: sh_mipi_dsi: add VMLEN1/VMLEN2 calculation VMLEN1/VMLEN2 needs blanking length which is calculated from video image size. The calculation methods are explained on [SH MIPI] - [Video Mode] - [Blanking Packet setting] But HFPLEN (= VMLEN2) is un-understandable. For example, if SH-MIPI input was RGB888 (3byte), output was RGB888 (3byte) and 3lane connection, the date goes straight. But if SH-MIPI input was RGB888 (3byte), output was RGB565 (2byte) and 4lane connection, it needs delay in HFPLEN. Then (input cycle - output cycle) * lane is necessary the delay Signed-off-by: Kuninori Morimoto Acked-by: Magnus Damm Signed-off-by: Florian Tobias Schandinat diff --git a/drivers/video/sh_mipi_dsi.c b/drivers/video/sh_mipi_dsi.c index b8c4873..190e941 100644 --- a/drivers/video/sh_mipi_dsi.c +++ b/drivers/video/sh_mipi_dsi.c @@ -42,6 +42,7 @@ #define VMCTR1 0x0020 #define VMCTR2 0x0024 #define VMLEN1 0x0028 +#define VMLEN2 0x002c #define CMTSRTREQ 0x0070 #define CMTSRTCTR 0x00d0 @@ -153,8 +154,9 @@ static int __init sh_mipi_setup(struct sh_mipi *mipi, void __iomem *base = mipi->base; struct sh_mobile_lcdc_chan_cfg *ch = pdata->lcd_chan; u32 pctype, datatype, pixfmt, linelength, vmctr2; + u32 tmp, top, bottom, delay; bool yuv; - u32 tmp; + int bpp; /* * Select data format. MIPI DSI is not hot-pluggable, so, we just use @@ -342,11 +344,44 @@ static int __init sh_mipi_setup(struct sh_mipi *mipi, iowrite32(vmctr2, mipi->linkbase + VMCTR2); /* - * 0x660 = 1632 bytes per line (RGB24, 544 pixels: see - * sh_mobile_lcdc_info.ch[0].lcd_cfg[0].xres), HSALEN = 1 - default - * (unused if VMCTR2[HSABM] = 0) + * VMLEN1 = RGBLEN | HSALEN + * + * see + * Video mode - Blanking Packet setting */ - iowrite32(1 | (linelength << 16), mipi->linkbase + VMLEN1); + top = linelength << 16; /* RGBLEN */ + bottom = 0x00000001; + if (pdata->flags & SH_MIPI_DSI_HSABM) /* HSALEN */ + bottom = (pdata->lane * ch->lcd_cfg[0].hsync_len) - 10; + iowrite32(top | bottom , mipi->linkbase + VMLEN1); + + /* + * VMLEN2 = HBPLEN | HFPLEN + * + * see + * Video mode - Blanking Packet setting + */ + top = 0x00010000; + bottom = 0x00000001; + delay = 0; + + if (pdata->flags & SH_MIPI_DSI_HFPBM) { /* HBPLEN */ + top = ch->lcd_cfg[0].hsync_len + ch->lcd_cfg[0].left_margin; + top = ((pdata->lane * top) - 10) << 16; + } + if (pdata->flags & SH_MIPI_DSI_HBPBM) { /* HFPLEN */ + bottom = ch->lcd_cfg[0].right_margin; + bottom = (pdata->lane * bottom) - 12; + } + + bpp = linelength / ch->lcd_cfg[0].xres; /* byte / pixel */ + if (pdata->lane > bpp) { + tmp = ch->lcd_cfg[0].xres / bpp; /* output cycle */ + tmp = ch->lcd_cfg[0].xres - tmp; /* (input - output) cycle */ + delay = (pdata->lane * tmp); + } + + iowrite32(top | (bottom + delay) , mipi->linkbase + VMLEN2); msleep(5); -- cgit v0.10.2 From 5e47431aabf716c9ad9eacf1a966e1fc1469c809 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Tue, 8 Nov 2011 20:35:14 -0800 Subject: fbdev: sh_mipi_dsi: add set_dot_clock() for each platform Dot clock of SH MIPI are depends on each platform board. This patch adds set_dot_clock() function for it. Signed-off-by: Kuninori Morimoto Acked-by: Magnus Damm Signed-off-by: Florian Tobias Schandinat diff --git a/arch/arm/mach-shmobile/board-ag5evm.c b/arch/arm/mach-shmobile/board-ag5evm.c index 6993844..15072c5 100644 --- a/arch/arm/mach-shmobile/board-ag5evm.c +++ b/arch/arm/mach-shmobile/board-ag5evm.c @@ -321,6 +321,36 @@ static struct resource mipidsi0_resources[] = { }, }; +#define DSI0PHYCR 0xe615006c +static int sh_mipi_set_dot_clock(struct platform_device *pdev, + void __iomem *base, + int enable) +{ + struct clk *pck; + int ret; + + pck = clk_get(&pdev->dev, "dsip_clk"); + if (IS_ERR(pck)) { + ret = PTR_ERR(pck); + goto sh_mipi_set_dot_clock_pck_err; + } + + if (enable) { + clk_set_rate(pck, clk_round_rate(pck, 24000000)); + __raw_writel(0x2a809010, DSI0PHYCR); + clk_enable(pck); + } else { + clk_disable(pck); + } + + ret = 0; + + clk_put(pck); + +sh_mipi_set_dot_clock_pck_err: + return ret; +} + static struct sh_mipi_dsi_info mipidsi0_info = { .data_format = MIPI_RGB888, .lcd_chan = &lcdc0_info.ch[0], @@ -329,6 +359,7 @@ static struct sh_mipi_dsi_info mipidsi0_info = { .clksrc = 1, .flags = SH_MIPI_DSI_HSABM | SH_MIPI_DSI_SYNC_PULSES_MODE, + .set_dot_clock = sh_mipi_set_dot_clock, }; static struct platform_device mipidsi0_device = { @@ -476,8 +507,6 @@ static void __init ag5evm_map_io(void) shmobile_setup_console(); } -#define DSI0PHYCR 0xe615006c - static void __init ag5evm_init(void) { sh73a0_pinmux_init(); @@ -558,9 +587,6 @@ static void __init ag5evm_init(void) gpio_direction_output(GPIO_PORT235, 0); lcd_backlight_reset(); - /* MIPI-DSI clock setup */ - __raw_writel(0x2a809010, DSI0PHYCR); - /* enable SDHI0 on CN15 [SD I/F] */ gpio_request(GPIO_FN_SDHICD0, NULL); gpio_request(GPIO_FN_SDHIWP0, NULL); diff --git a/arch/arm/mach-shmobile/board-ap4evb.c b/arch/arm/mach-shmobile/board-ap4evb.c index b2e32c8..73503ed 100644 --- a/arch/arm/mach-shmobile/board-ap4evb.c +++ b/arch/arm/mach-shmobile/board-ap4evb.c @@ -564,6 +564,30 @@ static struct platform_device keysc_device = { }; /* MIPI-DSI */ +#define PHYCTRL 0x0070 +static int sh_mipi_set_dot_clock(struct platform_device *pdev, + void __iomem *base, + int enable) +{ + struct clk *pck = clk_get(&pdev->dev, "dsip_clk"); + void __iomem *phy = base + PHYCTRL; + + if (IS_ERR(pck)) + return PTR_ERR(pck); + + if (enable) { + clk_set_rate(pck, clk_round_rate(pck, 24000000)); + iowrite32(ioread32(phy) | (0xb << 8), phy); + clk_enable(pck); + } else { + clk_disable(pck); + } + + clk_put(pck); + + return 0; +} + static struct resource mipidsi0_resources[] = { [0] = { .start = 0xffc60000, @@ -583,6 +607,7 @@ static struct sh_mipi_dsi_info mipidsi0_info = { .lane = 2, .vsynw_offset = 17, .flags = SH_MIPI_DSI_SYNC_PULSES_MODE, + .set_dot_clock = sh_mipi_set_dot_clock, }; static struct platform_device mipidsi0_device = { diff --git a/drivers/video/sh_mipi_dsi.c b/drivers/video/sh_mipi_dsi.c index 190e941..77743f4 100644 --- a/drivers/video/sh_mipi_dsi.c +++ b/drivers/video/sh_mipi_dsi.c @@ -53,7 +53,6 @@ struct sh_mipi { void __iomem *base; void __iomem *linkbase; struct clk *dsit_clk; - struct clk *dsip_clk; struct device *dev; void *next_board_data; @@ -307,8 +306,8 @@ static int __init sh_mipi_setup(struct sh_mipi *mipi, /* DSI-Tx bias on */ iowrite32(0x00000001, base + PHYCTRL); udelay(200); - /* Deassert resets, power on, set multiplier */ - iowrite32(0x03070b01, base + PHYCTRL); + /* Deassert resets, power on */ + iowrite32(0x03070001, base + PHYCTRL); /* setup l-bridge */ @@ -421,6 +420,9 @@ static int __init sh_mipi_probe(struct platform_device *pdev) if (!res || !res2 || idx >= ARRAY_SIZE(mipi_dsi) || !pdata) return -ENODEV; + if (!pdata->set_dot_clock) + return -EINVAL; + mutex_lock(&array_lock); if (idx < 0) for (idx = 0; idx < ARRAY_SIZE(mipi_dsi) && mipi_dsi[idx]; idx++) @@ -481,34 +483,10 @@ static int __init sh_mipi_probe(struct platform_device *pdev) dev_dbg(&pdev->dev, "DSI-T clk %lu -> %lu\n", f_current, rate); - mipi->dsip_clk = clk_get(&pdev->dev, "dsip_clk"); - if (IS_ERR(mipi->dsip_clk)) { - ret = PTR_ERR(mipi->dsip_clk); - goto eclkpget; - } - - f_current = clk_get_rate(mipi->dsip_clk); - /* Between 10 and 50MHz */ - rate = clk_round_rate(mipi->dsip_clk, 24000000); - if (rate > 0 && rate != f_current) - ret = clk_set_rate(mipi->dsip_clk, rate); - else - ret = rate; - if (ret < 0) - goto esetprate; - - dev_dbg(&pdev->dev, "DSI-P clk %lu -> %lu\n", f_current, rate); - - msleep(10); - ret = clk_enable(mipi->dsit_clk); if (ret < 0) goto eclkton; - ret = clk_enable(mipi->dsip_clk); - if (ret < 0) - goto eclkpon; - mipi_dsi[idx] = mipi; pm_runtime_enable(&pdev->dev); @@ -518,6 +496,10 @@ static int __init sh_mipi_probe(struct platform_device *pdev) if (ret < 0) goto emipisetup; + ret = pdata->set_dot_clock(pdev, mipi->base, 1); + if (ret < 0) + goto emipisetup; + mutex_unlock(&array_lock); platform_set_drvdata(pdev, mipi); @@ -537,13 +519,8 @@ static int __init sh_mipi_probe(struct platform_device *pdev) emipisetup: mipi_dsi[idx] = NULL; pm_runtime_disable(&pdev->dev); - clk_disable(mipi->dsip_clk); -eclkpon: clk_disable(mipi->dsit_clk); eclkton: -esetprate: - clk_put(mipi->dsip_clk); -eclkpget: esettrate: clk_put(mipi->dsit_clk); eclktget: @@ -594,10 +571,10 @@ static int __exit sh_mipi_remove(struct platform_device *pdev) pdata->lcd_chan->board_cfg.board_data = NULL; pm_runtime_disable(&pdev->dev); - clk_disable(mipi->dsip_clk); clk_disable(mipi->dsit_clk); clk_put(mipi->dsit_clk); - clk_put(mipi->dsip_clk); + pdata->set_dot_clock(pdev, mipi->base, 0); + iounmap(mipi->linkbase); if (res2) release_mem_region(res2->start, resource_size(res2)); diff --git a/include/video/sh_mipi_dsi.h b/include/video/sh_mipi_dsi.h index c8225b4..310b883 100644 --- a/include/video/sh_mipi_dsi.h +++ b/include/video/sh_mipi_dsi.h @@ -48,6 +48,9 @@ struct sh_mipi_dsi_info { unsigned long flags; u32 clksrc; unsigned int vsynw_offset; + int (*set_dot_clock)(struct platform_device *pdev, + void __iomem *base, + int enable); }; #endif -- cgit v0.10.2 From a2e6297153f8fc7185d119c59d8eed1ee7d4c74f Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Tue, 8 Nov 2011 20:35:27 -0800 Subject: fbdev: sh_mipi_dsi: add HSxxCLK support SH MIPI manual explains the calculation method of HBP/HFP. it is based on HSbyteCLK settings. SH73a0 chip can use HS6divCLK/HS4divCLK for it. This patch has compatibility to SH7372 mipi Signed-off-by: Kuninori Morimoto Acked-by: Magnus Damm Signed-off-by: Florian Tobias Schandinat diff --git a/arch/arm/mach-shmobile/board-ag5evm.c b/arch/arm/mach-shmobile/board-ag5evm.c index 15072c5..7e3dd73 100644 --- a/arch/arm/mach-shmobile/board-ag5evm.c +++ b/arch/arm/mach-shmobile/board-ag5evm.c @@ -357,8 +357,9 @@ static struct sh_mipi_dsi_info mipidsi0_info = { .lane = 2, .vsynw_offset = 20, .clksrc = 1, - .flags = SH_MIPI_DSI_HSABM | - SH_MIPI_DSI_SYNC_PULSES_MODE, + .flags = SH_MIPI_DSI_HSABM | + SH_MIPI_DSI_SYNC_PULSES_MODE | + SH_MIPI_DSI_HSbyteCLK, .set_dot_clock = sh_mipi_set_dot_clock, }; diff --git a/arch/arm/mach-shmobile/board-ap4evb.c b/arch/arm/mach-shmobile/board-ap4evb.c index 73503ed..904b608 100644 --- a/arch/arm/mach-shmobile/board-ap4evb.c +++ b/arch/arm/mach-shmobile/board-ap4evb.c @@ -606,7 +606,8 @@ static struct sh_mipi_dsi_info mipidsi0_info = { .lcd_chan = &lcdc_info.ch[0], .lane = 2, .vsynw_offset = 17, - .flags = SH_MIPI_DSI_SYNC_PULSES_MODE, + .flags = SH_MIPI_DSI_SYNC_PULSES_MODE | + SH_MIPI_DSI_HSbyteCLK, .set_dot_clock = sh_mipi_set_dot_clock, }; diff --git a/drivers/video/sh_mipi_dsi.c b/drivers/video/sh_mipi_dsi.c index 77743f4..b8aea8c 100644 --- a/drivers/video/sh_mipi_dsi.c +++ b/drivers/video/sh_mipi_dsi.c @@ -153,7 +153,7 @@ static int __init sh_mipi_setup(struct sh_mipi *mipi, void __iomem *base = mipi->base; struct sh_mobile_lcdc_chan_cfg *ch = pdata->lcd_chan; u32 pctype, datatype, pixfmt, linelength, vmctr2; - u32 tmp, top, bottom, delay; + u32 tmp, top, bottom, delay, div; bool yuv; int bpp; @@ -364,17 +364,23 @@ static int __init sh_mipi_setup(struct sh_mipi *mipi, bottom = 0x00000001; delay = 0; + div = 1; /* HSbyteCLK is calculation base + * HS4divCLK = HSbyteCLK/2 + * HS6divCLK is not supported for now */ + if (pdata->flags & SH_MIPI_DSI_HS4divCLK) + div = 2; + if (pdata->flags & SH_MIPI_DSI_HFPBM) { /* HBPLEN */ top = ch->lcd_cfg[0].hsync_len + ch->lcd_cfg[0].left_margin; - top = ((pdata->lane * top) - 10) << 16; + top = ((pdata->lane * top / div) - 10) << 16; } if (pdata->flags & SH_MIPI_DSI_HBPBM) { /* HFPLEN */ bottom = ch->lcd_cfg[0].right_margin; - bottom = (pdata->lane * bottom) - 12; + bottom = (pdata->lane * bottom / div) - 12; } bpp = linelength / ch->lcd_cfg[0].xres; /* byte / pixel */ - if (pdata->lane > bpp) { + if ((pdata->lane / div) > bpp) { tmp = ch->lcd_cfg[0].xres / bpp; /* output cycle */ tmp = ch->lcd_cfg[0].xres - tmp; /* (input - output) cycle */ delay = (pdata->lane * tmp); diff --git a/include/video/sh_mipi_dsi.h b/include/video/sh_mipi_dsi.h index 310b883..434d56b 100644 --- a/include/video/sh_mipi_dsi.h +++ b/include/video/sh_mipi_dsi.h @@ -35,6 +35,10 @@ struct sh_mobile_lcdc_chan_cfg; #define SH_MIPI_DSI_HSEE (1 << 5) #define SH_MIPI_DSI_HSAE (1 << 6) +#define SH_MIPI_DSI_HSbyteCLK (1 << 24) +#define SH_MIPI_DSI_HS6divCLK (1 << 25) +#define SH_MIPI_DSI_HS4divCLK (1 << 26) + #define SH_MIPI_DSI_SYNC_PULSES_MODE (SH_MIPI_DSI_VSEE | \ SH_MIPI_DSI_HSEE | \ SH_MIPI_DSI_HSAE) -- cgit v0.10.2 From 7d9f88b4f427df6dab7ff92ea81f1ddb7e9c95e4 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Tue, 8 Nov 2011 20:35:36 -0800 Subject: fbdev: sh_mipi_dsi: sh_mipi has pdata instead of dev Signed-off-by: Kuninori Morimoto Acked-by: Magnus Damm Signed-off-by: Florian Tobias Schandinat diff --git a/drivers/video/sh_mipi_dsi.c b/drivers/video/sh_mipi_dsi.c index b8aea8c..7e46505 100644 --- a/drivers/video/sh_mipi_dsi.c +++ b/drivers/video/sh_mipi_dsi.c @@ -53,7 +53,7 @@ struct sh_mipi { void __iomem *base; void __iomem *linkbase; struct clk *dsit_clk; - struct device *dev; + struct platform_device *pdev; void *next_board_data; void (*next_display_on)(void *board_data, struct fb_info *info); @@ -129,7 +129,7 @@ static void mipi_display_on(void *arg, struct fb_info *info) { struct sh_mipi *mipi = arg; - pm_runtime_get_sync(mipi->dev); + pm_runtime_get_sync(&mipi->pdev->dev); sh_mipi_dsi_enable(mipi, true); if (mipi->next_display_on) @@ -144,7 +144,7 @@ static void mipi_display_off(void *arg) mipi->next_display_off(mipi->next_board_data); sh_mipi_dsi_enable(mipi, false); - pm_runtime_put(mipi->dev); + pm_runtime_put(&mipi->pdev->dev); } static int __init sh_mipi_setup(struct sh_mipi *mipi, @@ -469,7 +469,7 @@ static int __init sh_mipi_probe(struct platform_device *pdev) goto emap2; } - mipi->dev = &pdev->dev; + mipi->pdev = pdev; mipi->dsit_clk = clk_get(&pdev->dev, "dsit_clk"); if (IS_ERR(mipi->dsit_clk)) { -- cgit v0.10.2 From c2658b70f06108361aa5024798f9c1bf47c73374 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Tue, 8 Nov 2011 20:35:45 -0800 Subject: fbdev: sh_mipi_dsi: fixup setup timing of sh_mipi_setup() sh_mipi_setup() should be called after setting of CPG Signed-off-by: Kuninori Morimoto Acked-by: Magnus Damm Signed-off-by: Florian Tobias Schandinat diff --git a/drivers/video/sh_mipi_dsi.c b/drivers/video/sh_mipi_dsi.c index 7e46505..f2c3f94 100644 --- a/drivers/video/sh_mipi_dsi.c +++ b/drivers/video/sh_mipi_dsi.c @@ -125,28 +125,6 @@ static void sh_mipi_shutdown(struct platform_device *pdev) sh_mipi_dsi_enable(mipi, false); } -static void mipi_display_on(void *arg, struct fb_info *info) -{ - struct sh_mipi *mipi = arg; - - pm_runtime_get_sync(&mipi->pdev->dev); - sh_mipi_dsi_enable(mipi, true); - - if (mipi->next_display_on) - mipi->next_display_on(mipi->next_board_data, info); -} - -static void mipi_display_off(void *arg) -{ - struct sh_mipi *mipi = arg; - - if (mipi->next_display_off) - mipi->next_display_off(mipi->next_board_data); - - sh_mipi_dsi_enable(mipi, false); - pm_runtime_put(&mipi->pdev->dev); -} - static int __init sh_mipi_setup(struct sh_mipi *mipi, struct sh_mipi_dsi_info *pdata) { @@ -414,6 +392,50 @@ static int __init sh_mipi_setup(struct sh_mipi *mipi, return 0; } +static void mipi_display_on(void *arg, struct fb_info *info) +{ + struct sh_mipi *mipi = arg; + struct sh_mipi_dsi_info *pdata = mipi->pdev->dev.platform_data; + int ret; + + pm_runtime_get_sync(&mipi->pdev->dev); + + ret = pdata->set_dot_clock(mipi->pdev, mipi->base, 1); + if (ret < 0) + goto mipi_display_on_fail1; + + ret = sh_mipi_setup(mipi, pdata); + if (ret < 0) + goto mipi_display_on_fail2; + + sh_mipi_dsi_enable(mipi, true); + + if (mipi->next_display_on) + mipi->next_display_on(mipi->next_board_data, info); + + return; + +mipi_display_on_fail1: + pm_runtime_put_sync(&mipi->pdev->dev); +mipi_display_on_fail2: + pdata->set_dot_clock(mipi->pdev, mipi->base, 0); +} + +static void mipi_display_off(void *arg) +{ + struct sh_mipi *mipi = arg; + struct sh_mipi_dsi_info *pdata = mipi->pdev->dev.platform_data; + + if (mipi->next_display_off) + mipi->next_display_off(mipi->next_board_data); + + sh_mipi_dsi_enable(mipi, false); + + pdata->set_dot_clock(mipi->pdev, mipi->base, 0); + + pm_runtime_put_sync(&mipi->pdev->dev); +} + static int __init sh_mipi_probe(struct platform_device *pdev) { struct sh_mipi *mipi; @@ -498,14 +520,6 @@ static int __init sh_mipi_probe(struct platform_device *pdev) pm_runtime_enable(&pdev->dev); pm_runtime_resume(&pdev->dev); - ret = sh_mipi_setup(mipi, pdata); - if (ret < 0) - goto emipisetup; - - ret = pdata->set_dot_clock(pdev, mipi->base, 1); - if (ret < 0) - goto emipisetup; - mutex_unlock(&array_lock); platform_set_drvdata(pdev, mipi); @@ -522,10 +536,6 @@ static int __init sh_mipi_probe(struct platform_device *pdev) return 0; -emipisetup: - mipi_dsi[idx] = NULL; - pm_runtime_disable(&pdev->dev); - clk_disable(mipi->dsit_clk); eclkton: esettrate: clk_put(mipi->dsit_clk); @@ -579,7 +589,6 @@ static int __exit sh_mipi_remove(struct platform_device *pdev) pm_runtime_disable(&pdev->dev); clk_disable(mipi->dsit_clk); clk_put(mipi->dsit_clk); - pdata->set_dot_clock(pdev, mipi->base, 0); iounmap(mipi->linkbase); if (res2) -- cgit v0.10.2 From a2065a368cc2539d6a48450f367f5033c699cdc4 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Tue, 8 Nov 2011 20:35:56 -0800 Subject: fbdev: sh_mipi_dsi: fixup setup timing of SYSCONF SYSCONF should be set after PHYCTRL Signed-off-by: Kuninori Morimoto Acked-by: Magnus Damm Signed-off-by: Florian Tobias Schandinat diff --git a/drivers/video/sh_mipi_dsi.c b/drivers/video/sh_mipi_dsi.c index f2c3f94..187e127 100644 --- a/drivers/video/sh_mipi_dsi.c +++ b/drivers/video/sh_mipi_dsi.c @@ -246,18 +246,6 @@ static int __init sh_mipi_setup(struct sh_mipi *mipi, /* setup DSI link */ /* - * Default = ULPS enable | - * Contention detection enabled | - * EoT packet transmission enable | - * CRC check enable | - * ECC check enable - * additionally enable first two lanes - */ - bitmap_fill((unsigned long *)&tmp, pdata->lane); - tmp |= 0x00003700; - iowrite32(tmp, base + SYSCONF); - - /* * T_wakeup = 0x7000 * T_hs-trail = 3 * T_hs-prepare = 3 @@ -287,6 +275,17 @@ static int __init sh_mipi_setup(struct sh_mipi *mipi, /* Deassert resets, power on */ iowrite32(0x03070001, base + PHYCTRL); + /* + * Default = ULPS enable | + * Contention detection enabled | + * EoT packet transmission enable | + * CRC check enable | + * ECC check enable + */ + bitmap_fill((unsigned long *)&tmp, pdata->lane); + tmp |= 0x00003700; + iowrite32(tmp, base + SYSCONF); + /* setup l-bridge */ /* -- cgit v0.10.2 From 97cab45583f75428773547f3bbe59fece05420d3 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Tue, 8 Nov 2011 20:36:07 -0800 Subject: fbdev: sh_mipi_dsi: fixup setup timing DSICTRL DSICTRL should be called after all mipi settings Signed-off-by: Kuninori Morimoto Acked-by: Magnus Damm Signed-off-by: Florian Tobias Schandinat diff --git a/drivers/video/sh_mipi_dsi.c b/drivers/video/sh_mipi_dsi.c index 187e127..05151b8 100644 --- a/drivers/video/sh_mipi_dsi.c +++ b/drivers/video/sh_mipi_dsi.c @@ -265,8 +265,6 @@ static int __init sh_mipi_setup(struct sh_mipi *mipi, iowrite32(0x0fffffff, base + TATOVSET); /* Peripheral reset timeout, default 0xffffffff */ iowrite32(0x0fffffff, base + PRTOVSET); - /* Enable timeout counters */ - iowrite32(0x00000f00, base + DSICTRL); /* Interrupts not used, disable all */ iowrite32(0, base + DSIINTE); /* DSI-Tx bias on */ @@ -388,6 +386,9 @@ static int __init sh_mipi_setup(struct sh_mipi *mipi, pixfmt << 4); sh_mipi_dcs(ch->chan, MIPI_DCS_SET_DISPLAY_ON); + /* Enable timeout counters */ + iowrite32(0x00000f00, base + DSICTRL); + return 0; } -- cgit v0.10.2 From 5345010cc8e87af7f1f48e5c816b10f96f474da1 Mon Sep 17 00:00:00 2001 From: Zac Storer Date: Thu, 17 Nov 2011 21:34:56 -0700 Subject: Drivers: video: controlfb: fixed a brace coding style issue Fixed a brace coding style issue. Signed-off-by: Zac Storer Signed-off-by: Florian Tobias Schandinat diff --git a/drivers/video/controlfb.c b/drivers/video/controlfb.c index 7b2c40a..0c189b3 100644 --- a/drivers/video/controlfb.c +++ b/drivers/video/controlfb.c @@ -420,7 +420,7 @@ static int __init init_control(struct fb_info_control *p) /* Try to pick a video mode out of NVRAM if we have one. */ #ifdef CONFIG_NVRAM - if (default_cmode == CMODE_NVRAM){ + if (default_cmode == CMODE_NVRAM) { cmode = nvram_read_byte(NV_CMODE); if(cmode < CMODE_8 || cmode > CMODE_32) cmode = CMODE_8; -- cgit v0.10.2 From 2dfd7cf6ce581621c5c0103f96cca7a9924b5f94 Mon Sep 17 00:00:00 2001 From: Zac Storer Date: Thu, 17 Nov 2011 21:38:58 -0700 Subject: Drivers: video: sbuslib: fixed a brace coding style issue Fixed a brace coding style issue. Signed-off-by: Zac Storer Signed-off-by: Florian Tobias Schandinat diff --git a/drivers/video/sbuslib.c b/drivers/video/sbuslib.c index 37d764a..3c1de98 100644 --- a/drivers/video/sbuslib.c +++ b/drivers/video/sbuslib.c @@ -76,7 +76,7 @@ int sbusfb_mmap_helper(struct sbus_mmap_map *map, map_offset = (physbase + map[i].poff) & POFF_MASK; break; } - if (!map_size){ + if (!map_size) { page += PAGE_SIZE; continue; } -- cgit v0.10.2 From 600bbf0aa2229390ba1c4ca4c5666c593ff9ef56 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 21 Nov 2011 20:12:04 -0500 Subject: ktest: Add default for ssh-user, build-target and target-image When a user runs ktest without an argument, or the argument given is not a config file that exists, ktest will ask the user a few questions to create a simple ktest config file. A few of the questions should have a default value set, that if anything it will make it easier for the user to know what is suppose to be in that value. These new values are: SSH_USER, BUILD_TARGET and TARGET_IMAGE Signed-off-by: Steven Rostedt diff --git a/tools/testing/ktest/ktest.pl b/tools/testing/ktest/ktest.pl index 6ef104e..05f429d 100755 --- a/tools/testing/ktest/ktest.pl +++ b/tools/testing/ktest/ktest.pl @@ -22,7 +22,6 @@ my %default; #default opts $default{"NUM_TESTS"} = 1; -$default{"REBOOT_TYPE"} = "grub"; $default{"TEST_TYPE"} = "test"; $default{"BUILD_TYPE"} = "randconfig"; $default{"MAKE_CMD"} = "make"; @@ -51,7 +50,14 @@ $default{"REBOOT"} = "ssh \$SSH_USER\@\$MACHINE reboot"; $default{"STOP_AFTER_SUCCESS"} = 10; $default{"STOP_AFTER_FAILURE"} = 60; $default{"STOP_TEST_AFTER"} = 600; + +# required, and we will ask users if they don't have them but we keep the default +# value something that is common. +$default{"REBOOT_TYPE"} = "grub"; $default{"LOCALVERSION"} = "-test"; +$default{"SSH_USER"} = "root"; +$default{"BUILD_TARGET"} = "arch/x86/boot/bzImage"; +$default{"TARGET_IMAGE"} = "/boot/vmlinuz-test"; my $ktest_config; my $version; -- cgit v0.10.2 From 9147621c771c8b6a5c8985373af3a8200e8b4a41 Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Tue, 22 Nov 2011 14:47:50 -0800 Subject: kbuild, headers.sh: Don't make archheaders explicitly We don't need to explicitly invoke the archheaders target because of the dependency on __headers in the Makefile. Reported-and-tested-by: Michal Marek Link: http://lkml.kernel.org/r/4ECA8991.20302@suse.cz Signed-off-by: H. Peter Anvin diff --git a/scripts/headers.sh b/scripts/headers.sh index af1ed88..978b42b 100755 --- a/scripts/headers.sh +++ b/scripts/headers.sh @@ -7,7 +7,6 @@ set -e do_command() { if [ -f ${srctree}/arch/$2/include/asm/Kbuild ]; then - make ARCH=$2 KBUILD_HEADERS=$1 archheaders make ARCH=$2 KBUILD_HEADERS=$1 headers_$1 else printf "Ignoring arch: %s\n" ${arch} -- cgit v0.10.2 From 60ec0eecfa8968d0f1188e3730979196ac28b9de Mon Sep 17 00:00:00 2001 From: Asai Thambi S P Date: Wed, 23 Nov 2011 08:29:24 +0100 Subject: mtip32xx: updates based on feedback * queue ncq commands when a non-ncq is in progress or error handling is active * merge variables 'internal_cmd_in_progress' and 'eh_active' into new variable 'flags' * get rid of read/write semaphore 'internal_sem' * new service thread to issue queued commands * use macros from ata.h for command codes * return ENOTTY for BLKFLSBUF ioctl * style changes Signed-off-by: Asai Thambi S P Signed-off-by: Sam Bradshaw Signed-off-by: Jens Axboe diff --git a/drivers/block/mtip32xx/mtip32xx.c b/drivers/block/mtip32xx/mtip32xx.c index 880facb..b5d843a 100644 --- a/drivers/block/mtip32xx/mtip32xx.c +++ b/drivers/block/mtip32xx/mtip32xx.c @@ -34,6 +34,7 @@ #include #include #include +#include #include <../drivers/ata/ahci.h> #include "mtip32xx.h" @@ -99,15 +100,6 @@ struct mtip_compat_ide_task_request_s { }; #endif -static int mtip_exec_internal_command(struct mtip_port *port, - void *fis, - int fisLen, - dma_addr_t buffer, - int bufLen, - u32 opts, - gfp_t atomic, - unsigned long timeout); - /* * This function check_for_surprise_removal is called * while card is removed from the system and it will @@ -414,9 +406,9 @@ static void mtip_init_port(struct mtip_port *port) port->mmio + PORT_FIS_ADDR_HI); } - writel(port->command_list_dma & 0xffffffff, + writel(port->command_list_dma & 0xFFFFFFFF, port->mmio + PORT_LST_ADDR); - writel(port->rxfis_dma & 0xffffffff, port->mmio + PORT_FIS_ADDR); + writel(port->rxfis_dma & 0xFFFFFFFF, port->mmio + PORT_FIS_ADDR); /* Clear SError */ writel(readl(port->mmio + PORT_SCR_ERR), port->mmio + PORT_SCR_ERR); @@ -541,7 +533,7 @@ static void mtip_timeout_function(unsigned long int data) if (atomic_read(&port->commands[tag].active) && (time_after(jiffies, port->commands[tag].comp_time))) { group = tag >> 5; - bit = tag & 0x1f; + bit = tag & 0x1F; command = &port->commands[tag]; fis = (struct host_to_dev_fis *) command->command; @@ -551,7 +543,7 @@ static void mtip_timeout_function(unsigned long int data) cmdto_cnt++; if (cmdto_cnt == 1) - atomic_inc(&port->dd->eh_active); + set_bit(MTIP_FLAG_EH_ACTIVE_BIT, &port->flags); /* * Clear the completed bit. This should prevent @@ -589,7 +581,8 @@ static void mtip_timeout_function(unsigned long int data) "%d commands timed out: restarting port", cmdto_cnt); mtip_restart_port(port); - atomic_dec(&port->dd->eh_active); + clear_bit(MTIP_FLAG_EH_ACTIVE_BIT, &port->flags); + wake_up_interruptible(&port->svc_wait); } /* Restart the timer */ @@ -728,7 +721,7 @@ static void mtip_handle_tfe(struct driver_data *dd) del_timer(&port->cmd_timer); /* Set eh_active */ - atomic_inc(&dd->eh_active); + set_bit(MTIP_FLAG_EH_ACTIVE_BIT, &port->flags); /* Loop through all the groups */ for (group = 0; group < dd->slot_groups; group++) { @@ -835,8 +828,9 @@ static void mtip_handle_tfe(struct driver_data *dd) } print_tags(dd, "TFE tags reissued:", tagaccum); - /* Decrement eh_active */ - atomic_dec(&dd->eh_active); + /* clear eh_active */ + clear_bit(MTIP_FLAG_EH_ACTIVE_BIT, &port->flags); + wake_up_interruptible(&port->svc_wait); mod_timer(&port->cmd_timer, jiffies + msecs_to_jiffies(MTIP_TIMEOUT_CHECK_PERIOD)); @@ -871,7 +865,6 @@ static inline void mtip_process_sdbf(struct driver_data *dd) continue; command = &port->commands[tag]; - /* make internal callback */ if (likely(command->comp_func)) { command->comp_func( @@ -904,9 +897,8 @@ static inline void mtip_process_legacy(struct driver_data *dd, u32 port_stat) struct mtip_port *port = dd->port; struct mtip_cmd *cmd = &port->commands[MTIP_TAG_INTERNAL]; - if (port->internal_cmd_in_progress && - cmd != NULL && - !(readl(port->cmd_issue[MTIP_TAG_INTERNAL]) + if (test_bit(MTIP_FLAG_IC_ACTIVE_BIT, &port->flags) && + (cmd != NULL) && !(readl(port->cmd_issue[MTIP_TAG_INTERNAL]) & (1 << MTIP_TAG_INTERNAL))) { if (cmd->comp_func) { cmd->comp_func(port, @@ -1038,11 +1030,15 @@ static int mtip_quiesce_io(struct mtip_port *port, unsigned long timeout) to = jiffies + msecs_to_jiffies(timeout); do { + if (test_bit(MTIP_FLAG_SVC_THD_ACTIVE_BIT, &port->flags)) { + msleep(20); + continue; /* svc thd is actively issuing commands */ + } /* * Ignore s_active bit 0 of array element 0. * This bit will always be set */ - active = readl(port->s_active[0]) & 0xfffffffe; + active = readl(port->s_active[0]) & 0xFFFFFFFE; for (n = 1; n < port->dd->slot_groups; n++) active |= readl(port->s_active[n]); @@ -1060,9 +1056,9 @@ static int mtip_quiesce_io(struct mtip_port *port, unsigned long timeout) * * @port Pointer to the port data structure. * @fis Pointer to the FIS that describes the command. - * @fisLen Length in WORDS of the FIS. + * @fis_len Length in WORDS of the FIS. * @buffer DMA accessible for command data. - * @bufLen Length, in bytes, of the data buffer. + * @buf_len Length, in bytes, of the data buffer. * @opts Command header options, excluding the FIS length * and the number of PRD entries. * @timeout Time in ms to wait for the command to complete. @@ -1075,9 +1071,9 @@ static int mtip_quiesce_io(struct mtip_port *port, unsigned long timeout) */ static int mtip_exec_internal_command(struct mtip_port *port, void *fis, - int fisLen, + int fis_len, dma_addr_t buffer, - int bufLen, + int buf_len, u32 opts, gfp_t atomic, unsigned long timeout) @@ -1100,7 +1096,7 @@ static int mtip_exec_internal_command(struct mtip_port *port, "Internal command already active\n"); return -EBUSY; } - port->internal_cmd_in_progress = 1; + set_bit(MTIP_FLAG_IC_ACTIVE_BIT, &port->flags); if (atomic == GFP_KERNEL) { /* wait for io to complete if non atomic */ @@ -1108,7 +1104,8 @@ static int mtip_exec_internal_command(struct mtip_port *port, dev_warn(&port->dd->pdev->dev, "Failed to quiesce IO\n"); release_slot(port, MTIP_TAG_INTERNAL); - port->internal_cmd_in_progress = 0; + clear_bit(MTIP_FLAG_IC_ACTIVE_BIT, &port->flags); + wake_up_interruptible(&port->svc_wait); return -EBUSY; } @@ -1123,19 +1120,23 @@ static int mtip_exec_internal_command(struct mtip_port *port, } /* Copy the command to the command table */ - memcpy(int_cmd->command, fis, fisLen*4); + memcpy(int_cmd->command, fis, fis_len*4); /* Populate the SG list */ int_cmd->command_header->opts = - cpu_to_le32(opts | fisLen); - if (bufLen) { + __force_bit2int cpu_to_le32(opts | fis_len); + if (buf_len) { command_sg = int_cmd->command + AHCI_CMD_TBL_HDR_SZ; - command_sg->info = cpu_to_le32((bufLen-1) & 0x3fffff); - command_sg->dba = cpu_to_le32(buffer & 0xffffffff); - command_sg->dba_upper = cpu_to_le32((buffer >> 16) >> 16); + command_sg->info = + __force_bit2int cpu_to_le32((buf_len-1) & 0x3FFFFF); + command_sg->dba = + __force_bit2int cpu_to_le32(buffer & 0xFFFFFFFF); + command_sg->dba_upper = + __force_bit2int cpu_to_le32((buffer >> 16) >> 16); - int_cmd->command_header->opts |= cpu_to_le32((1 << 16)); + int_cmd->command_header->opts |= + __force_bit2int cpu_to_le32((1 << 16)); } /* Populate the command header */ @@ -1151,8 +1152,9 @@ static int mtip_exec_internal_command(struct mtip_port *port, &wait, msecs_to_jiffies(timeout)) == 0) { dev_err(&port->dd->pdev->dev, - "Internal command did not complete [%d]\n", - atomic); + "Internal command did not complete [%d] " + "within timeout of %lu ms\n", + atomic, timeout); rv = -EAGAIN; } @@ -1184,7 +1186,8 @@ static int mtip_exec_internal_command(struct mtip_port *port, /* Clear the allocated and active bits for the internal command. */ atomic_set(&int_cmd->active, 0); release_slot(port, MTIP_TAG_INTERNAL); - port->internal_cmd_in_progress = 0; + clear_bit(MTIP_FLAG_IC_ACTIVE_BIT, &port->flags); + wake_up_interruptible(&port->svc_wait); return rv; } @@ -1233,8 +1236,6 @@ static int mtip_get_identify(struct mtip_port *port, void __user *user_buffer) int rv = 0; struct host_to_dev_fis fis; - down_write(&port->dd->internal_sem); - /* Build the FIS. */ memset(&fis, 0, sizeof(struct host_to_dev_fis)); fis.type = 0x27; @@ -1292,7 +1293,6 @@ static int mtip_get_identify(struct mtip_port *port, void __user *user_buffer) } out: - up_write(&port->dd->internal_sem); return rv; } @@ -1310,8 +1310,6 @@ static int mtip_standby_immediate(struct mtip_port *port) int rv; struct host_to_dev_fis fis; - down_write(&port->dd->internal_sem); - /* Build the FIS. */ memset(&fis, 0, sizeof(struct host_to_dev_fis)); fis.type = 0x27; @@ -1328,8 +1326,6 @@ static int mtip_standby_immediate(struct mtip_port *port) GFP_KERNEL, 15000); - up_write(&port->dd->internal_sem); - return rv; } @@ -1430,7 +1426,7 @@ static void mtip_dump_identify(struct mtip_port *port) ((u64)sectors) * ATA_SECT_SIZE >> 20); pci_read_config_word(port->dd->pdev, PCI_REVISION_ID, &revid); - switch (revid & 0xff) { + switch (revid & 0xFF) { case 0x1: strlcpy(cbuf, "A0", 3); break; @@ -1470,15 +1466,12 @@ static inline void fill_command_sg(struct driver_data *dd, if (dma_len > 0x400000) dev_err(&dd->pdev->dev, "DMA segment length truncated\n"); - command_sg->info = cpu_to_le32((dma_len-1) & 0x3fffff); -#if (BITS_PER_LONG == 64) - *((unsigned long *) &command_sg->dba) = - cpu_to_le64(sg_dma_address(sg)); -#else - command_sg->dba = cpu_to_le32(sg_dma_address(sg)); - command_sg->dba_upper = - cpu_to_le32((sg_dma_address(sg) >> 16) >> 16); -#endif + command_sg->info = __force_bit2int + cpu_to_le32((dma_len-1) & 0x3FFFFF); + command_sg->dba = __force_bit2int + cpu_to_le32(sg_dma_address(sg)); + command_sg->dba_upper = __force_bit2int + cpu_to_le32((sg_dma_address(sg) >> 16) >> 16); command_sg++; sg++; } @@ -1495,9 +1488,6 @@ static int exec_drive_task(struct mtip_port *port, u8 *command) struct host_to_dev_fis fis; struct host_to_dev_fis *reply = (port->rxfis + RX_FIS_D2H_REG); - /* Lock the internal command semaphore. */ - down_write(&port->dd->internal_sem); - /* Build the FIS. */ memset(&fis, 0, sizeof(struct host_to_dev_fis)); fis.type = 0x27; @@ -1532,7 +1522,6 @@ static int exec_drive_task(struct mtip_port *port, u8 *command) 0, GFP_KERNEL, MTIP_IOCTL_COMMAND_TIMEOUT_MS) < 0) { - up_write(&port->dd->internal_sem); return -1; } @@ -1549,7 +1538,6 @@ static int exec_drive_task(struct mtip_port *port, u8 *command) command[4], command[5]); - up_write(&port->dd->internal_sem); return 0; } @@ -1572,9 +1560,6 @@ static int exec_drive_command(struct mtip_port *port, u8 *command, struct host_to_dev_fis fis; struct host_to_dev_fis *reply = (port->rxfis + RX_FIS_D2H_REG); - /* Lock the internal command semaphore. */ - down_write(&port->dd->internal_sem); - /* Build the FIS. */ memset(&fis, 0, sizeof(struct host_to_dev_fis)); fis.type = 0x27; @@ -1584,8 +1569,8 @@ static int exec_drive_command(struct mtip_port *port, u8 *command, fis.sect_count = command[3]; if (fis.command == ATA_CMD_SMART) { fis.sector = command[1]; - fis.cyl_low = 0x4f; - fis.cyl_hi = 0xc2; + fis.cyl_low = 0x4F; + fis.cyl_hi = 0xC2; } dbg_printk(MTIP_DRV_NAME @@ -1609,7 +1594,6 @@ static int exec_drive_command(struct mtip_port *port, u8 *command, GFP_KERNEL, MTIP_IOCTL_COMMAND_TIMEOUT_MS) < 0) { - up_write(&port->dd->internal_sem); return -1; } @@ -1630,12 +1614,10 @@ static int exec_drive_command(struct mtip_port *port, u8 *command, if (copy_to_user(user_buffer, port->sector_buffer, ATA_SECT_SIZE * command[3])) { - up_write(&port->dd->internal_sem); return -EFAULT; } } - up_write(&port->dd->internal_sem); return 0; } @@ -1658,26 +1640,28 @@ static unsigned int implicit_sector(unsigned char command, /* list of commands that have an implicit sector count of 1 */ switch (command) { - case 0xF1: - case 0xF2: - case 0xF3: - case 0xF4: - case 0xF5: - case 0xF6: - case 0xE4: - case 0xE8: + case ATA_CMD_SEC_SET_PASS: + case ATA_CMD_SEC_UNLOCK: + case ATA_CMD_SEC_ERASE_PREP: + case ATA_CMD_SEC_ERASE_UNIT: + case ATA_CMD_SEC_FREEZE_LOCK: + case ATA_CMD_SEC_DISABLE_PASS: + case ATA_CMD_PMP_READ: + case ATA_CMD_PMP_WRITE: rv = 1; break; - case 0xF9: - if (features == 0x03) + case ATA_CMD_SET_MAX: + if (features == ATA_SET_MAX_UNLOCK) rv = 1; break; - case 0xB0: - if ((features == 0xD0) || (features == 0xD1)) + case ATA_CMD_SMART: + if ((features == ATA_SMART_READ_VALUES) || + (features == ATA_SMART_READ_THRESHOLDS)) rv = 1; break; - case 0xB1: - if ((features == 0xC2) || (features == 0xC3)) + case ATA_CMD_CONF_OVERLAY: + if ((features == ATA_DCO_IDENTIFY) || + (features == ATA_DCO_SET)) rv = 1; break; } @@ -1777,9 +1761,6 @@ static int exec_drive_taskfile(struct driver_data *dd, goto abort; } - /* Lock the internal command semaphore. */ - down_write(&dd->internal_sem); - /* Build the FIS. */ memset(&fis, 0, sizeof(struct host_to_dev_fis)); @@ -1818,7 +1799,6 @@ static int exec_drive_taskfile(struct driver_data *dd, dev_warn(&dd->pdev->dev, "data movement but " "sect_count is 0\n"); - up_write(&dd->internal_sem); err = -EINVAL; goto abort; } @@ -1838,19 +1818,25 @@ static int exec_drive_taskfile(struct driver_data *dd, fis.device); switch (fis.command) { - case 0x92: /* Change timeout for Download Microcode to 60 seconds.*/ + case ATA_CMD_DOWNLOAD_MICRO: + /* Change timeout for Download Microcode to 60 seconds.*/ timeout = 60000; break; - case 0xf4: /* Change timeout for Security Erase Unit to 4 minutes.*/ + case ATA_CMD_SEC_ERASE_UNIT: + /* Change timeout for Security Erase Unit to 4 minutes.*/ timeout = 240000; break; - case 0xe0: /* Change timeout for standby immediate to 10 seconds.*/ + case ATA_CMD_STANDBYNOW1: + /* Change timeout for standby immediate to 10 seconds.*/ timeout = 10000; break; - case 0xf7: /* Change timeout for vendor unique command to 10 secs */ + case 0xF7: + case 0xFA: + /* Change timeout for vendor unique command to 10 secs */ timeout = 10000; break; - case 0xfa: /* Change timeout for vendor unique command to 10 secs */ + case ATA_CMD_SMART: + /* Change timeout for vendor unique command to 10 secs */ timeout = 10000; break; default: @@ -1873,7 +1859,6 @@ static int exec_drive_taskfile(struct driver_data *dd, 0, GFP_KERNEL, timeout) < 0) { - up_write(&dd->internal_sem); err = -EIO; goto abort; } @@ -1916,7 +1901,7 @@ static int exec_drive_taskfile(struct driver_data *dd, } /* Com rest after secure erase or lowlevel format */ - if (((fis.command == 0xF4) || + if (((fis.command == ATA_CMD_SEC_ERASE_UNIT) || ((fis.command == 0xFC) && (fis.features == 0x27 || fis.features == 0x72 || fis.features == 0x62 || fis.features == 0x26))) && @@ -1937,8 +1922,6 @@ static int exec_drive_taskfile(struct driver_data *dd, req_task->io_ports[5], req_task->io_ports[6]); - up_write(&dd->internal_sem); - if (taskout) { if (copy_to_user(buf + outtotal, outbuf, taskout)) { err = -EFAULT; @@ -2052,7 +2035,8 @@ static int mtip_hw_ioctl(struct driver_data *dd, unsigned int cmd, ret = exec_drive_taskfile(dd, (void __user *) arg, &req_task, outtotal); - if (copy_to_user((void __user *) arg, &req_task, sizeof(req_task))) + if (copy_to_user((void __user *) arg, &req_task, + sizeof(req_task))) return -EFAULT; return ret; @@ -2117,13 +2101,13 @@ static void mtip_hw_submit_io(struct driver_data *dd, sector_t start, fis->opts = 1 << 7; fis->command = (dir == READ ? ATA_CMD_FPDMA_READ : ATA_CMD_FPDMA_WRITE); - *((unsigned int *) &fis->lba_low) = (start & 0xffffff); - *((unsigned int *) &fis->lba_low_ex) = ((start >> 24) & 0xffffff); + *((unsigned int *) &fis->lba_low) = (start & 0xFFFFFF); + *((unsigned int *) &fis->lba_low_ex) = ((start >> 24) & 0xFFFFFF); fis->device = 1 << 6; if (barrier) fis->device |= FUA_BIT; - fis->features = nsect & 0xff; - fis->features_ex = (nsect >> 8) & 0xff; + fis->features = nsect & 0xFF; + fis->features_ex = (nsect >> 8) & 0xFF; fis->sect_count = ((tag << 3) | (tag >> 5)); fis->sect_cnt_ex = 0; fis->control = 0; @@ -2132,8 +2116,9 @@ static void mtip_hw_submit_io(struct driver_data *dd, sector_t start, fill_command_sg(dd, command, nents); /* Populate the command header */ - command->command_header->opts = cpu_to_le32( - (nents << 16) | 5 | AHCI_CMD_PREFETCH); + command->command_header->opts = + __force_bit2int cpu_to_le32( + (nents << 16) | 5 | AHCI_CMD_PREFETCH); command->command_header->byte_count = 0; /* @@ -2152,10 +2137,15 @@ static void mtip_hw_submit_io(struct driver_data *dd, sector_t start, command->async_callback = callback; /* - * Lock used to prevent this command from being issued - * if an internal command is in progress. + * To prevent this command from being issued + * if an internal command is in progress or error handling is active. */ - down_read(&port->dd->internal_sem); + if (unlikely(test_bit(MTIP_FLAG_IC_ACTIVE_BIT, &port->flags) || + test_bit(MTIP_FLAG_EH_ACTIVE_BIT, &port->flags))) { + set_bit(tag, port->cmds_to_issue); + set_bit(MTIP_FLAG_ISSUE_CMDS_BIT, &port->flags); + return; + } /* Issue the command to the hardware */ mtip_issue_ncq_command(port, tag); @@ -2163,8 +2153,6 @@ static void mtip_hw_submit_io(struct driver_data *dd, sector_t start, /* Set the command's timeout value.*/ port->commands[tag].comp_time = jiffies + msecs_to_jiffies( MTIP_NCQ_COMMAND_TIMEOUT_MS); - - up_read(&port->dd->internal_sem); } /* @@ -2400,10 +2388,9 @@ static int mtip_ftl_rebuild_poll(struct driver_data *dd) timeout = jiffies + msecs_to_jiffies(MTIP_FTL_REBUILD_TIMEOUT_MS); do { -#ifdef CONFIG_HOTPLUG if (mtip_check_surprise_removal(dd->pdev)) return -EFAULT; -#endif + if (mtip_get_identify(dd->port, NULL) < 0) return -EFAULT; @@ -2439,6 +2426,74 @@ static int mtip_ftl_rebuild_poll(struct driver_data *dd) } /* + * service thread to issue queued commands + * + * @data Pointer to the driver data structure. + * + * return value + * 0 + */ + +static int mtip_service_thread(void *data) +{ + struct driver_data *dd = (struct driver_data *)data; + unsigned long slot, slot_start, slot_wrap; + unsigned int num_cmd_slots = dd->slot_groups * 32; + struct mtip_port *port = dd->port; + + while (1) { + /* + * the condition is to check neither an internal command is + * is in progress nor error handling is active + */ + wait_event_interruptible(port->svc_wait, (port->flags) && + !test_bit(MTIP_FLAG_IC_ACTIVE_BIT, &port->flags) && + !test_bit(MTIP_FLAG_EH_ACTIVE_BIT, &port->flags)); + + if (kthread_should_stop()) + break; + + if (test_bit(MTIP_FLAG_ISSUE_CMDS_BIT, &port->flags)) { + set_bit(MTIP_FLAG_SVC_THD_ACTIVE_BIT, &port->flags); + slot = 1; + /* used to restrict the loop to one iteration */ + slot_start = num_cmd_slots; + slot_wrap = 0; + while (1) { + slot = find_next_bit(port->cmds_to_issue, + num_cmd_slots, slot); + if (slot_wrap == 1) { + if ((slot_start >= slot) || + (slot >= num_cmd_slots)) + break; + } + if (unlikely(slot_start == num_cmd_slots)) + slot_start = slot; + + if (unlikely(slot == num_cmd_slots)) { + slot = 1; + slot_wrap = 1; + continue; + } + + /* Issue the command to the hardware */ + mtip_issue_ncq_command(port, slot); + + /* Set the command's timeout value.*/ + port->commands[slot].comp_time = jiffies + + msecs_to_jiffies(MTIP_NCQ_COMMAND_TIMEOUT_MS); + + clear_bit(slot, port->cmds_to_issue); + } + + clear_bit(MTIP_FLAG_ISSUE_CMDS_BIT, &port->flags); + clear_bit(MTIP_FLAG_SVC_THD_ACTIVE_BIT, &port->flags); + } + } + return 0; +} + +/* * Called once for each card. * * @dd Pointer to the driver data structure. @@ -2463,13 +2518,6 @@ static int mtip_hw_init(struct driver_data *dd) hba_setup(dd); - /* - * Initialize the internal semaphore - * Use a rw semaphore to enable prioritization of - * mgmnt ioctl traffic during heavy IO load - */ - init_rwsem(&dd->internal_sem); - tasklet_init(&dd->tasklet, mtip_tasklet, (unsigned long)dd); dd->port = kzalloc(sizeof(struct mtip_port), GFP_KERNEL); @@ -2541,10 +2589,11 @@ static int mtip_hw_init(struct driver_data *dd) if (readl(dd->mmio + HOST_CAP) & HOST_CAP_64) dd->port->commands[i].command_header->ctbau = - cpu_to_le32( + __force_bit2int cpu_to_le32( (dd->port->commands[i].command_dma >> 16) >> 16); - dd->port->commands[i].command_header->ctba = cpu_to_le32( - dd->port->commands[i].command_dma & 0xffffffff); + dd->port->commands[i].command_header->ctba = + __force_bit2int cpu_to_le32( + dd->port->commands[i].command_dma & 0xFFFFFFFF); /* * If this is not done, a bug is reported by the stock @@ -2597,6 +2646,8 @@ static int mtip_hw_init(struct driver_data *dd) dd->mmio + HOST_CTL); init_timer(&dd->port->cmd_timer); + init_waitqueue_head(&dd->port->svc_wait); + dd->port->cmd_timer.data = (unsigned long int) dd->port; dd->port->cmd_timer.function = mtip_timeout_function; mod_timer(&dd->port->cmd_timer, @@ -2667,12 +2718,12 @@ static int mtip_hw_exit(struct driver_data *dd) del_timer_sync(&dd->port->cmd_timer); - /* Stop the bottom half tasklet. */ - tasklet_kill(&dd->tasklet); - /* Release the IRQ. */ devm_free_irq(&dd->pdev->dev, dd->pdev->irq, dd); + /* Stop the bottom half tasklet. */ + tasklet_kill(&dd->tasklet); + /* Free the command/command header memory. */ dmam_free_coherent(&dd->pdev->dev, HW_PORT_PRIV_DMA_SZ + (ATA_SECT_SIZE * 2), @@ -2835,7 +2886,7 @@ static int mtip_block_ioctl(struct block_device *dev, switch (cmd) { case BLKFLSBUF: - return 0; + return -ENOTTY; default: return mtip_hw_ioctl(dd, cmd, arg); } @@ -2870,19 +2921,20 @@ static int mtip_block_compat_ioctl(struct block_device *dev, switch (cmd) { case BLKFLSBUF: - return 0; + return -ENOTTY; case HDIO_DRIVE_TASKFILE: { - struct mtip_compat_ide_task_request_s *compat_req_task; + struct mtip_compat_ide_task_request_s __user *compat_req_task; ide_task_request_t req_task; int compat_tasksize, outtotal, ret; - compat_tasksize = sizeof(struct mtip_compat_ide_task_request_s); + compat_tasksize = + sizeof(struct mtip_compat_ide_task_request_s); compat_req_task = (struct mtip_compat_ide_task_request_s __user *) arg; if (copy_from_user(&req_task, (void __user *) arg, - compat_tasksize - (2 * sizeof(compat_long_t)))) + compat_tasksize - (2 * sizeof(compat_long_t)))) return -EFAULT; if (get_user(req_task.out_size, &compat_req_task->out_size)) @@ -2950,12 +3002,8 @@ static int mtip_block_getgeo(struct block_device *dev, geo->heads = 224; geo->sectors = 56; -#if BITS_PER_LONG == 64 - geo->cylinders = capacity / (geo->heads * geo->sectors); -#else - do_div(capacity, (geo->heads * geo->sectors)); + sector_div(capacity, (geo->heads * geo->sectors)); geo->cylinders = capacity; -#endif return 0; } @@ -2999,11 +3047,6 @@ static void mtip_make_request(struct request_queue *queue, struct bio *bio) return; } - if (unlikely(atomic_read(&dd->eh_active))) { - bio_endio(bio, -EBUSY); - return; - } - sg = mtip_hw_get_scatterlist(dd, &tag); if (likely(sg != NULL)) { blk_queue_bounce(queue, &bio); @@ -3032,7 +3075,7 @@ static void mtip_make_request(struct request_queue *queue, struct bio *bio) tag, bio_endio, bio, - bio->bi_rw & REQ_FLUSH, + bio->bi_rw & REQ_FUA, bio_data_dir(bio)); } else bio_io_error(bio); @@ -3055,6 +3098,7 @@ static int mtip_block_initialize(struct driver_data *dd) sector_t capacity; unsigned int index = 0; struct kobject *kobj; + unsigned char thd_name[16]; /* Initialize the protocol layer. */ rv = mtip_hw_init(dd); @@ -3082,6 +3126,7 @@ static int mtip_block_initialize(struct driver_data *dd) blk_queue_max_segments(dd->queue, MTIP_MAX_SG); blk_queue_physical_block_size(dd->queue, 4096); blk_queue_io_min(dd->queue, 4096); + blk_queue_flush(dd->queue, 0); dd->disk = alloc_disk(MTIP_MAX_MINORS); if (dd->disk == NULL) { @@ -3142,6 +3187,18 @@ static int mtip_block_initialize(struct driver_data *dd) kobject_put(kobj); } + sprintf(thd_name, "mtip_svc_thd_%02d", index); + + dd->mtip_svc_handler = kthread_run(mtip_service_thread, + dd, thd_name); + + if (IS_ERR(dd->mtip_svc_handler)) { + printk(KERN_ERR "mtip32xx: service thread failed to start\n"); + dd->mtip_svc_handler = NULL; + rv = -EFAULT; + goto read_capacity_error; + } + return rv; read_capacity_error: @@ -3183,6 +3240,13 @@ protocol_init_error: static int mtip_block_remove(struct driver_data *dd) { struct kobject *kobj; + + if (dd->mtip_svc_handler) { + set_bit(MTIP_FLAG_SVC_THD_SHOULD_STOP_BIT, &dd->port->flags); + wake_up_interruptible(&dd->port->svc_wait); + kthread_stop(dd->mtip_svc_handler); + } + /* Clean up the sysfs attributes managed by the protocol layer. */ kobj = kobject_get(&disk_to_dev(dd->disk)->kobj); if (kobj) { @@ -3275,7 +3339,6 @@ static int mtip_pci_probe(struct pci_dev *pdev, atomic_set(&dd->drv_cleanup_done, true); atomic_set(&dd->resumeflag, false); - atomic_set(&dd->eh_active, 0); /* Attach the private data to this PCI device. */ pci_set_drvdata(pdev, dd); @@ -3317,7 +3380,6 @@ static int mtip_pci_probe(struct pci_dev *pdev, /* Copy the info we may need later into the private data structure. */ dd->major = mtip_major; - dd->protocol = ent->driver_data; dd->instance = instance; dd->pdev = pdev; diff --git a/drivers/block/mtip32xx/mtip32xx.h b/drivers/block/mtip32xx/mtip32xx.h index 17be4f4..933192a 100644 --- a/drivers/block/mtip32xx/mtip32xx.h +++ b/drivers/block/mtip32xx/mtip32xx.h @@ -47,11 +47,11 @@ /* ftl rebuild */ #define MTIP_FTL_REBUILD_OFFSET 142 -#define MTIP_FTL_REBUILD_MAGIC 0xed51 +#define MTIP_FTL_REBUILD_MAGIC 0xED51 #define MTIP_FTL_REBUILD_TIMEOUT_MS 2400000 /* Macro to extract the tag bit number from a tag value. */ -#define MTIP_TAG_BIT(tag) (tag & 0x1f) +#define MTIP_TAG_BIT(tag) (tag & 0x1F) /* * Macro to extract the tag index from a tag value. The index @@ -81,7 +81,7 @@ /* Driver name and version strings */ #define MTIP_DRV_NAME "mtip32xx" -#define MTIP_DRV_VERSION "1.2.6os2" +#define MTIP_DRV_VERSION "1.2.6os3" /* Maximum number of minor device numbers per device. */ #define MTIP_MAX_MINORS 16 @@ -114,6 +114,15 @@ #define dbg_printk(format, arg...) #endif +#define __force_bit2int (unsigned int __force) + +/* below are bit numbers in 'flags' defined in mtip_port */ +#define MTIP_FLAG_IC_ACTIVE_BIT 0 +#define MTIP_FLAG_EH_ACTIVE_BIT 1 +#define MTIP_FLAG_SVC_THD_ACTIVE_BIT 2 +#define MTIP_FLAG_ISSUE_CMDS_BIT 4 +#define MTIP_FLAG_SVC_THD_SHOULD_STOP_BIT 8 + /* Register Frame Information Structure (FIS), host to device. */ struct host_to_dev_fis { /* @@ -262,7 +271,7 @@ struct mtip_cmd { unsigned long comp_time; /* command completion time, in jiffies */ - atomic_t active; /* declares if this command sent to the drive. */ + atomic_t active; /* declares if this command sent to the drive. */ }; /* Structure used to describe a port. */ @@ -278,7 +287,7 @@ struct mtip_port { void __iomem *mmio; /* Array of pointers to the memory mapped s_active registers. */ void __iomem *s_active[MTIP_MAX_SLOT_GROUPS]; - /* Array of pointers to the memory mapped completed registers. */ + /* Array of pointers to the memory mapped completed registers. */ void __iomem *completed[MTIP_MAX_SLOT_GROUPS]; /* Array of pointers to the memory mapped Command Issue registers. */ void __iomem *cmd_issue[MTIP_MAX_SLOT_GROUPS]; @@ -340,13 +349,23 @@ struct mtip_port { */ unsigned long allocated[SLOTBITS_IN_LONGS]; /* + * used to queue commands when an internal command is in progress + * or error handling is active + */ + unsigned long cmds_to_issue[SLOTBITS_IN_LONGS]; + /* * Array of command slots. Structure includes pointers to the * command header and command table, and completion function and data * pointers. */ struct mtip_cmd commands[MTIP_MAX_COMMAND_SLOTS]; - /* Non-zero if an internal command is in progress. */ - int internal_cmd_in_progress; + /* Used by mtip_service_thread to wait for an event */ + wait_queue_head_t svc_wait; + /* + * indicates the state of the port. Also, helps the service thread + * to determine its action on wake up. + */ + unsigned long flags; /* * Timer used to complete commands that have been active for too long. */ @@ -372,18 +391,11 @@ struct driver_data { int instance; /* Instance number. First device probed is 0, ... */ - int protocol; /* FIXME: Protocol ops array index. */ - struct gendisk *disk; /* Pointer to our gendisk structure. */ struct pci_dev *pdev; /* Pointer to the PCI device structure. */ struct request_queue *queue; /* Our request queue. */ - /* - * Semaphore used to lock out read/write commands during the - * execution of an internal command. - */ - struct rw_semaphore internal_sem; struct mtip_port *port; /* Pointer to the port data structure. */ @@ -403,6 +415,8 @@ struct driver_data { atomic_t resumeflag; /* Atomic variable to track suspend/resume */ atomic_t eh_active; /* Flag for error handling tracking */ + + struct task_struct *mtip_svc_handler; /* task_struct of svc thd */ }; #endif -- cgit v0.10.2 From 0e7a22de25212cfcaa0ba2c957e4e60eaa70fb9d Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 21 Nov 2011 20:39:33 -0500 Subject: ktest: When creating new config, allow the use of ${THIS_DIR} Typing in a full path when you know that the path exists within the directory your are running is tedious and unnecessary. Allow the user to use ${PWD} if they want a dynamic path name which will be the path that ktest.pl is executed from or use ${THIS_DIR} which is a variable assigned `pwd` and the the variable will exist within the config, allowing the user to change it and affect all other paths using this variable as well Signed-off-by: Steven Rostedt diff --git a/tools/testing/ktest/ktest.pl b/tools/testing/ktest/ktest.pl index 05f429d..77b4649 100755 --- a/tools/testing/ktest/ktest.pl +++ b/tools/testing/ktest/ktest.pl @@ -158,11 +158,15 @@ EOF ; $config_help{"BUILD_DIR"} = << "EOF" The directory that contains the Linux source code (full path). + You can use \${PWD} that will be the path where ktest.pl is run, or use + \${THIS_DIR} which is assigned \${PWD} but may be changed later. EOF ; $config_help{"OUTPUT_DIR"} = << "EOF" The directory that the objects will be built (full path). (can not be same as BUILD_DIR) + You can use \${PWD} that will be the path where ktest.pl is run, or use + \${THIS_DIR} which is assigned \${PWD} but may be changed later. EOF ; $config_help{"BUILD_TARGET"} = << "EOF" @@ -282,7 +286,7 @@ sub get_ktest_config { next; } } - $entered_configs{$config} = process_variables($ans); + $entered_configs{$config} = ${ans}; last; } } @@ -3012,6 +3016,17 @@ if (! -f $ktest_config) { print OUT << "EOF" # Generated by ktest.pl # + +# PWD is a ktest.pl variable that will result in the process working +# directory that ktest.pl is executed in. + +# THIS_DIR is automatically assigned the PWD of the path that generated +# the config file. It is best to use this variable when assigning other +# directory paths within this directory. This allows you to easily +# move the test cases to other locations or to other machines. +# +THIS_DIR := $variable{"PWD"} + # Define each test with TEST_START # The config options below it will override the defaults TEST_START @@ -3034,7 +3049,7 @@ if ($#new_configs >= 0) { open(OUT, ">>$ktest_config") or die "Can not append to $ktest_config"; foreach my $config (@new_configs) { print OUT "$config = $entered_configs{$config}\n"; - $opt{$config} = $entered_configs{$config}; + $opt{$config} = process_variables($entered_configs{$config}); } } -- cgit v0.10.2 From 39cac3758f62c6495d954e0d7dc1ca7e69fa565d Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 23 Nov 2011 12:03:32 -0300 Subject: [media] ir-nec-decoder: Report what bit failed at debug msg Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/rc/ir-nec-decoder.c b/drivers/media/rc/ir-nec-decoder.c index 63ee722..a825318 100644 --- a/drivers/media/rc/ir-nec-decoder.c +++ b/drivers/media/rc/ir-nec-decoder.c @@ -193,8 +193,8 @@ static int ir_nec_decode(struct rc_dev *dev, struct ir_raw_event ev) return 0; } - IR_dprintk(1, "NEC decode failed at state %d (%uus %s)\n", - data->state, TO_US(ev.duration), TO_STR(ev.pulse)); + IR_dprintk(1, "NEC decode failed at count %d state %d (%uus %s)\n", + data->count, data->state, TO_US(ev.duration), TO_STR(ev.pulse)); data->state = STATE_INACTIVE; return -EINVAL; } -- cgit v0.10.2 From b32e724308300a6ecead0f4895f0452a06a4291d Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 23 Nov 2011 12:04:08 -0300 Subject: [media] rc: Add support for decoding Sanyo protocol This protocol is found on Sanyo/Aiwa remotes. Tested with an Aiwa RC-7AS06 remote control. Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/rc/Kconfig b/drivers/media/rc/Kconfig index aeb7f43..4df4aff 100644 --- a/drivers/media/rc/Kconfig +++ b/drivers/media/rc/Kconfig @@ -87,6 +87,16 @@ config IR_RC5_SZ_DECODER uses an IR protocol that is almost standard RC-5, but not quite, as it uses an additional bit). +config IR_SANYO_DECODER + tristate "Enable IR raw decoder for the Sanyo protocol" + depends on RC_CORE + default y + + ---help--- + Enable this option if you have an infrared remote control which + uses the Sanyo protocol (Sanyo, Aiwa, Chinon remotes), + and you need software decoding support. + config IR_MCE_KBD_DECODER tristate "Enable IR raw decoder for the MCE keyboard/mouse protocol" depends on RC_CORE diff --git a/drivers/media/rc/Makefile b/drivers/media/rc/Makefile index 2156e78..fb3dee2 100644 --- a/drivers/media/rc/Makefile +++ b/drivers/media/rc/Makefile @@ -10,6 +10,7 @@ obj-$(CONFIG_IR_RC6_DECODER) += ir-rc6-decoder.o obj-$(CONFIG_IR_JVC_DECODER) += ir-jvc-decoder.o obj-$(CONFIG_IR_SONY_DECODER) += ir-sony-decoder.o obj-$(CONFIG_IR_RC5_SZ_DECODER) += ir-rc5-sz-decoder.o +obj-$(CONFIG_IR_SANYO_DECODER) += ir-sanyo-decoder.o obj-$(CONFIG_IR_MCE_KBD_DECODER) += ir-mce_kbd-decoder.o obj-$(CONFIG_IR_LIRC_CODEC) += ir-lirc-codec.o diff --git a/drivers/media/rc/ir-raw.c b/drivers/media/rc/ir-raw.c index 27808bb..9e841f4 100644 --- a/drivers/media/rc/ir-raw.c +++ b/drivers/media/rc/ir-raw.c @@ -355,6 +355,7 @@ static void init_decoders(struct work_struct *work) load_rc6_decode(); load_jvc_decode(); load_sony_decode(); + load_sanyo_decode(); load_mce_kbd_decode(); load_lirc_codec(); diff --git a/drivers/media/rc/ir-sanyo-decoder.c b/drivers/media/rc/ir-sanyo-decoder.c new file mode 100644 index 0000000..1646730 --- /dev/null +++ b/drivers/media/rc/ir-sanyo-decoder.c @@ -0,0 +1,204 @@ +/* ir-sanyo-decoder.c - handle SANYO IR Pulse/Space protocol + * + * Copyright (C) 2011 by Mauro Carvalho Chehab + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * This protocol uses the NEC protocol timings. However, data is formatted as: + * 13 bits Custom Code + * 13 bits NOT(Custom Code) + * 8 bits Key data + * 8 bits NOT(Key data) + * + * According with LIRC, this protocol is used on Sanyo, Aiwa and Chinon + * Information for this protocol is available at the Sanyo LC7461 datasheet. + */ + +#include +#include "rc-core-priv.h" + +#define SANYO_NBITS (13+13+8+8) +#define SANYO_UNIT 562500 /* ns */ +#define SANYO_HEADER_PULSE (16 * SANYO_UNIT) +#define SANYO_HEADER_SPACE (8 * SANYO_UNIT) +#define SANYO_BIT_PULSE (1 * SANYO_UNIT) +#define SANYO_BIT_0_SPACE (1 * SANYO_UNIT) +#define SANYO_BIT_1_SPACE (3 * SANYO_UNIT) +#define SANYO_REPEAT_SPACE (150 * SANYO_UNIT) +#define SANYO_TRAILER_PULSE (1 * SANYO_UNIT) +#define SANYO_TRAILER_SPACE (10 * SANYO_UNIT) /* in fact, 42 */ + +enum sanyo_state { + STATE_INACTIVE, + STATE_HEADER_SPACE, + STATE_BIT_PULSE, + STATE_BIT_SPACE, + STATE_TRAILER_PULSE, + STATE_TRAILER_SPACE, +}; + +/** + * ir_sanyo_decode() - Decode one SANYO pulse or space + * @dev: the struct rc_dev descriptor of the device + * @duration: the struct ir_raw_event descriptor of the pulse/space + * + * This function returns -EINVAL if the pulse violates the state machine + */ +static int ir_sanyo_decode(struct rc_dev *dev, struct ir_raw_event ev) +{ + struct sanyo_dec *data = &dev->raw->sanyo; + u32 scancode; + u8 address, not_address, command, not_command; + + if (!(dev->raw->enabled_protocols & RC_TYPE_SANYO)) + return 0; + + if (!is_timing_event(ev)) { + if (ev.reset) { + IR_dprintk(1, "SANYO event reset received. reset to state 0\n"); + data->state = STATE_INACTIVE; + } + return 0; + } + + IR_dprintk(2, "SANYO decode started at state %d (%uus %s)\n", + data->state, TO_US(ev.duration), TO_STR(ev.pulse)); + + switch (data->state) { + + case STATE_INACTIVE: + if (!ev.pulse) + break; + + if (eq_margin(ev.duration, SANYO_HEADER_PULSE, SANYO_UNIT / 2)) { + data->count = 0; + data->state = STATE_HEADER_SPACE; + return 0; + } + break; + + + case STATE_HEADER_SPACE: + if (ev.pulse) + break; + + if (eq_margin(ev.duration, SANYO_HEADER_SPACE, SANYO_UNIT / 2)) { + data->state = STATE_BIT_PULSE; + return 0; + } + + break; + + case STATE_BIT_PULSE: + if (!ev.pulse) + break; + + if (!eq_margin(ev.duration, SANYO_BIT_PULSE, SANYO_UNIT / 2)) + break; + + data->state = STATE_BIT_SPACE; + return 0; + + case STATE_BIT_SPACE: + if (ev.pulse) + break; + + if (!data->count && geq_margin(ev.duration, SANYO_REPEAT_SPACE, SANYO_UNIT / 2)) { + if (!dev->keypressed) { + IR_dprintk(1, "SANYO discarding last key repeat: event after key up\n"); + } else { + rc_repeat(dev); + IR_dprintk(1, "SANYO repeat last key\n"); + data->state = STATE_INACTIVE; + } + return 0; + } + + data->bits <<= 1; + if (eq_margin(ev.duration, SANYO_BIT_1_SPACE, SANYO_UNIT / 2)) + data->bits |= 1; + else if (!eq_margin(ev.duration, SANYO_BIT_0_SPACE, SANYO_UNIT / 2)) + break; + data->count++; + + if (data->count == SANYO_NBITS) + data->state = STATE_TRAILER_PULSE; + else + data->state = STATE_BIT_PULSE; + + return 0; + + case STATE_TRAILER_PULSE: + if (!ev.pulse) + break; + + if (!eq_margin(ev.duration, SANYO_TRAILER_PULSE, SANYO_UNIT / 2)) + break; + + data->state = STATE_TRAILER_SPACE; + return 0; + + case STATE_TRAILER_SPACE: + if (ev.pulse) + break; + + if (!geq_margin(ev.duration, SANYO_TRAILER_SPACE, SANYO_UNIT / 2)) + break; + + address = bitrev16((data->bits >> 29) & 0x1fff) >> 3; + not_address = bitrev16((data->bits >> 16) & 0x1fff) >> 3; + command = bitrev8((data->bits >> 8) & 0xff); + not_command = bitrev8((data->bits >> 0) & 0xff); + + if ((command ^ not_command) != 0xff) { + IR_dprintk(1, "SANYO checksum error: received 0x%08Lx\n", + data->bits); + data->state = STATE_INACTIVE; + return 0; + } + + scancode = address << 8 | command; + IR_dprintk(1, "SANYO scancode: 0x%06x\n", scancode); + rc_keydown(dev, scancode, 0); + data->state = STATE_INACTIVE; + return 0; + } + + IR_dprintk(1, "SANYO decode failed at count %d state %d (%uus %s)\n", + data->count, data->state, TO_US(ev.duration), TO_STR(ev.pulse)); + data->state = STATE_INACTIVE; + return -EINVAL; +} + +static struct ir_raw_handler sanyo_handler = { + .protocols = RC_TYPE_SANYO, + .decode = ir_sanyo_decode, +}; + +static int __init ir_sanyo_decode_init(void) +{ + ir_raw_handler_register(&sanyo_handler); + + printk(KERN_INFO "IR SANYO protocol handler initialized\n"); + return 0; +} + +static void __exit ir_sanyo_decode_exit(void) +{ + ir_raw_handler_unregister(&sanyo_handler); +} + +module_init(ir_sanyo_decode_init); +module_exit(ir_sanyo_decode_exit); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Mauro Carvalho Chehab "); +MODULE_AUTHOR("Red Hat Inc. (http://www.redhat.com)"); +MODULE_DESCRIPTION("SANYO IR protocol decoder"); diff --git a/drivers/media/rc/rc-core-priv.h b/drivers/media/rc/rc-core-priv.h index c6ca870..b72f858 100644 --- a/drivers/media/rc/rc-core-priv.h +++ b/drivers/media/rc/rc-core-priv.h @@ -84,6 +84,11 @@ struct ir_raw_event_ctrl { unsigned count; unsigned wanted_bits; } rc5_sz; + struct sanyo_dec { + int state; + unsigned count; + u64 bits; + } sanyo; struct mce_kbd_dec { struct input_dev *idev; struct timer_list rx_timeout; @@ -193,6 +198,13 @@ static inline void load_jvc_decode(void) { } static inline void load_sony_decode(void) { } #endif +/* from ir-sanyo-decoder.c */ +#ifdef CONFIG_IR_SANYO_DECODER_MODULE +#define load_sanyo_decode() request_module("ir-sanyo-decoder") +#else +static inline void load_sanyo_decode(void) { } +#endif + /* from ir-mce_kbd-decoder.c */ #ifdef CONFIG_IR_MCE_KBD_DECODER_MODULE #define load_mce_kbd_decode() request_module("ir-mce_kbd-decoder") diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c index 666d4bb..35e2fcf 100644 --- a/drivers/media/rc/rc-main.c +++ b/drivers/media/rc/rc-main.c @@ -735,6 +735,7 @@ static struct { { RC_TYPE_JVC, "jvc" }, { RC_TYPE_SONY, "sony" }, { RC_TYPE_RC5_SZ, "rc-5-sz" }, + { RC_TYPE_SANYO, "sanyo" }, { RC_TYPE_MCE_KBD, "mce_kbd" }, { RC_TYPE_LIRC, "lirc" }, { RC_TYPE_OTHER, "other" }, diff --git a/include/media/rc-map.h b/include/media/rc-map.h index 26a3bd0..183d701 100644 --- a/include/media/rc-map.h +++ b/include/media/rc-map.h @@ -18,13 +18,15 @@ #define RC_TYPE_JVC (1 << 3) /* JVC protocol */ #define RC_TYPE_SONY (1 << 4) /* Sony12/15/20 protocol */ #define RC_TYPE_RC5_SZ (1 << 5) /* RC5 variant used by Streamzap */ +#define RC_TYPE_SANYO (1 << 6) /* Sanyo protocol */ #define RC_TYPE_MCE_KBD (1 << 29) /* RC6-ish MCE keyboard/mouse */ #define RC_TYPE_LIRC (1 << 30) /* Pass raw IR to lirc userspace */ #define RC_TYPE_OTHER (1u << 31) -#define RC_TYPE_ALL (RC_TYPE_RC5 | RC_TYPE_NEC | RC_TYPE_RC6 | \ - RC_TYPE_JVC | RC_TYPE_SONY | RC_TYPE_LIRC | \ - RC_TYPE_RC5_SZ | RC_TYPE_MCE_KBD | RC_TYPE_OTHER) +#define RC_TYPE_ALL (RC_TYPE_RC5 | RC_TYPE_NEC | RC_TYPE_RC6 | \ + RC_TYPE_JVC | RC_TYPE_SONY | RC_TYPE_LIRC | \ + RC_TYPE_RC5_SZ | RC_TYPE_SANYO | RC_TYPE_MCE_KBD | \ + RC_TYPE_OTHER) struct rc_map_table { u32 scancode; -- cgit v0.10.2 From db9bc660cf4d1a09565f5db2bab9d3b86e3e32a5 Mon Sep 17 00:00:00 2001 From: lawrence rust Date: Mon, 31 Oct 2011 08:39:32 -0300 Subject: [media] ir-rc6-decoder: Support RC6-6A variable length data This patch to the IR RC6 decoder adds support for variable length mode-6A frames which can range in size from 8 to 128 bits. Please refer to the following link for a detailed explanation or RC6 frames: http://slydiman.narod.ru/scr/kb/rc6.htm This change removes the assumption that frames are fixed length (currently either 24 or 32 data bits) and actually counts the number of bits until an end of frame marker is seen. [mchehab@redhat.com: Tested with a RC-6(0) IR - 16 bits] Tested-by: Mauro Carvalho Chehab Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/rc/ir-rc6-decoder.c b/drivers/media/rc/ir-rc6-decoder.c index 140fb67..4cfdd7f 100644 --- a/drivers/media/rc/ir-rc6-decoder.c +++ b/drivers/media/rc/ir-rc6-decoder.c @@ -18,24 +18,31 @@ /* * This decoder currently supports: * RC6-0-16 (standard toggle bit in header) + * RC6-6A-20 (no toggle bit) * RC6-6A-24 (no toggle bit) * RC6-6A-32 (MCE version with toggle bit in body) */ -#define RC6_UNIT 444444 /* us */ +#define RC6_UNIT 444444 /* nanosecs */ #define RC6_HEADER_NBITS 4 /* not including toggle bit */ #define RC6_0_NBITS 16 -#define RC6_6A_SMALL_NBITS 24 -#define RC6_6A_LARGE_NBITS 32 +#define RC6_6A_32_NBITS 32 +#define RC6_6A_NBITS 128 /* Variable 8..128 */ #define RC6_PREFIX_PULSE (6 * RC6_UNIT) #define RC6_PREFIX_SPACE (2 * RC6_UNIT) #define RC6_BIT_START (1 * RC6_UNIT) #define RC6_BIT_END (1 * RC6_UNIT) #define RC6_TOGGLE_START (2 * RC6_UNIT) #define RC6_TOGGLE_END (2 * RC6_UNIT) +#define RC6_SUFFIX_SPACE (6 * RC6_UNIT) #define RC6_MODE_MASK 0x07 /* for the header bits */ #define RC6_STARTBIT_MASK 0x08 /* for the header bits */ #define RC6_6A_MCE_TOGGLE_MASK 0x8000 /* for the body bits */ +#define RC6_6A_LCC_MASK 0xffff0000 /* RC6-6A-32 long customer code mask */ +#define RC6_6A_MCE_CC 0x800f0000 /* MCE customer code */ +#ifndef CHAR_BIT +#define CHAR_BIT 8 /* Normally in */ +#endif enum rc6_mode { RC6_MODE_0, @@ -125,6 +132,7 @@ again: break; data->state = STATE_HEADER_BIT_START; + data->header = 0; return 0; case STATE_HEADER_BIT_START: @@ -171,20 +179,14 @@ again: data->state = STATE_BODY_BIT_START; decrease_duration(&ev, RC6_TOGGLE_END); data->count = 0; + data->body = 0; switch (rc6_mode(data)) { case RC6_MODE_0: data->wanted_bits = RC6_0_NBITS; break; case RC6_MODE_6A: - /* This might look weird, but we basically - check the value of the first body bit to - determine the number of bits in mode 6A */ - if ((!ev.pulse && !geq_margin(ev.duration, RC6_UNIT, RC6_UNIT / 2)) || - geq_margin(ev.duration, RC6_UNIT, RC6_UNIT / 2)) - data->wanted_bits = RC6_6A_LARGE_NBITS; - else - data->wanted_bits = RC6_6A_SMALL_NBITS; + data->wanted_bits = RC6_6A_NBITS; break; default: IR_dprintk(1, "RC6 unknown mode\n"); @@ -193,15 +195,21 @@ again: goto again; case STATE_BODY_BIT_START: - if (!eq_margin(ev.duration, RC6_BIT_START, RC6_UNIT / 2)) - break; - - data->body <<= 1; - if (ev.pulse) - data->body |= 1; - data->count++; - data->state = STATE_BODY_BIT_END; - return 0; + if (eq_margin(ev.duration, RC6_BIT_START, RC6_UNIT / 2)) { + /* Discard LSB's that won't fit in data->body */ + if (data->count++ < CHAR_BIT * sizeof data->body) { + data->body <<= 1; + if (ev.pulse) + data->body |= 1; + } + data->state = STATE_BODY_BIT_END; + return 0; + } else if (RC6_MODE_6A == rc6_mode(data) && !ev.pulse && + geq_margin(ev.duration, RC6_SUFFIX_SPACE, RC6_UNIT / 2)) { + data->state = STATE_FINISHED; + goto again; + } + break; case STATE_BODY_BIT_END: if (!is_transition(&ev, &dev->raw->prev_ev)) @@ -221,20 +229,27 @@ again: switch (rc6_mode(data)) { case RC6_MODE_0: - scancode = data->body & 0xffff; + scancode = data->body; toggle = data->toggle; IR_dprintk(1, "RC6(0) scancode 0x%04x (toggle: %u)\n", scancode, toggle); break; case RC6_MODE_6A: - if (data->wanted_bits == RC6_6A_LARGE_NBITS) { - toggle = data->body & RC6_6A_MCE_TOGGLE_MASK ? 1 : 0; - scancode = data->body & ~RC6_6A_MCE_TOGGLE_MASK; + if (data->count > CHAR_BIT * sizeof data->body) { + IR_dprintk(1, "RC6 too many (%u) data bits\n", + data->count); + goto out; + } + + scancode = data->body; + if (data->count == RC6_6A_32_NBITS && + (scancode & RC6_6A_LCC_MASK) == RC6_6A_MCE_CC) { + /* MCE RC */ + toggle = (scancode & RC6_6A_MCE_TOGGLE_MASK) ? 1 : 0; + scancode &= ~RC6_6A_MCE_TOGGLE_MASK; } else { toggle = 0; - scancode = data->body & 0xffffff; } - IR_dprintk(1, "RC6(6A) scancode 0x%08x (toggle: %u)\n", scancode, toggle); break; -- cgit v0.10.2 From 3e54a3d1b83220d748f1a27c8999634be7a83949 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 24 Nov 2011 12:59:00 +0100 Subject: mtip32xx: uninitialized variable in mtip_quiesce_io() We recently introduce new continue in the loop which make gcc complain. In theory if MTIP_FLAG_SVC_THD_ACTIVE_BIT is set, we could hit continue over and over until eventually we time out of the loop. In that case "active" should be set as true, but right now it's uninitialized. Signed-off-by: Dan Carpenter Signed-off-by: Jens Axboe diff --git a/drivers/block/mtip32xx/mtip32xx.c b/drivers/block/mtip32xx/mtip32xx.c index b5d843a..9bc10e3 100644 --- a/drivers/block/mtip32xx/mtip32xx.c +++ b/drivers/block/mtip32xx/mtip32xx.c @@ -1026,7 +1026,8 @@ static void mtip_issue_non_ncq_command(struct mtip_port *port, int tag) static int mtip_quiesce_io(struct mtip_port *port, unsigned long timeout) { unsigned long to; - unsigned int n, active; + unsigned int n; + unsigned int active = 1; to = jiffies + msecs_to_jiffies(timeout); do { -- cgit v0.10.2 From e469183541ac108fbc9bcf8e73c2061f049be620 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Mon, 7 Nov 2011 14:44:12 -0300 Subject: [media] V4L: mt9t112: use after free in mt9t112_probe() priv gets dereferenced in mt9t112_set_params() so we should return before calling that. Signed-off-by: Dan Carpenter Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/mt9t112.c b/drivers/media/video/mt9t112.c index 32114a3..7b34b11 100644 --- a/drivers/media/video/mt9t112.c +++ b/drivers/media/video/mt9t112.c @@ -1083,8 +1083,10 @@ static int mt9t112_probe(struct i2c_client *client, v4l2_i2c_subdev_init(&priv->subdev, client, &mt9t112_subdev_ops); ret = mt9t112_camera_probe(client); - if (ret) + if (ret) { kfree(priv); + return ret; + } /* Cannot fail: using the default supported pixel code */ mt9t112_set_params(priv, &rect, V4L2_MBUS_FMT_UYVY8_2X8); -- cgit v0.10.2 From 2e962f4efa944d47bbfacdd7f93fb21a99272357 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Thu, 24 Nov 2011 08:47:51 -0300 Subject: [media] ir-sanyo-decoder.c doesn't compile I get this error when compiling for_v3.3: There is a include missing. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/rc/ir-sanyo-decoder.c b/drivers/media/rc/ir-sanyo-decoder.c index 1646730..d38fbdd 100644 --- a/drivers/media/rc/ir-sanyo-decoder.c +++ b/drivers/media/rc/ir-sanyo-decoder.c @@ -21,6 +21,7 @@ * Information for this protocol is available at the Sanyo LC7461 datasheet. */ +#include #include #include "rc-core-priv.h" -- cgit v0.10.2 From a23d9d1227f05cf96d195401fe2af2c14ea44b92 Mon Sep 17 00:00:00 2001 From: Jose Alberto Reguero Date: Sun, 16 Oct 2011 07:36:57 -0300 Subject: [media] TT CT-3650 i2c fix This patch fix a bug in the i2c code of ttusb2 driver. Signed-off-by: Jose Alberto Reguero Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/dvb/dvb-usb/ttusb2.c b/drivers/media/dvb/dvb-usb/ttusb2.c index faed393..bc50356 100644 --- a/drivers/media/dvb/dvb-usb/ttusb2.c +++ b/drivers/media/dvb/dvb-usb/ttusb2.c @@ -397,7 +397,7 @@ static int ttusb2_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msg[],int num memcpy(&obuf[3], msg[i].buf, msg[i].len); - if (ttusb2_msg(d, CMD_I2C_XFER, obuf, msg[i].len+3, ibuf, obuf[2] + 3) < 0) { + if (ttusb2_msg(d, CMD_I2C_XFER, obuf, obuf[1]+3, ibuf, obuf[2] + 3) < 0) { err("i2c transfer failed."); break; } -- cgit v0.10.2 From 9369cc96af2d5e093ed7f0ac9671f4b30d30af86 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Tue, 18 Oct 2011 02:12:09 -0300 Subject: [media] av7110: wrong limiter in av7110_start_feed() Smatch complains that the wrong limiter is used here: drivers/media/dvb/ttpci/av7110.c +906 dvb_feed_start_pid(12) error: buffer overflow 'npids' 5 <= 19 Here is the problem code: 905 i = dvbdmxfeed->pes_type; 906 npids[i] = (pid[i]&0x8000) ? 0 : pid[i]; "npids" is a 5 element array declared on the stack. If dvbdmxfeed->pes_type is more than 4 we probably put a (u16)0 past the end of the array. If dvbdmxfeed->pes_type is over 4 the rest of the function doesn't do anything. dvbdmxfeed->pes_type is capped at less than DMX_TS_PES_OTHER (20) in the caller function, but I changed it to less than or equal to DMX_TS_PES_PCR (4). Signed-off-by: Dan Carpenter Acked-by: Oliver Endriss Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/dvb/ttpci/av7110.c b/drivers/media/dvb/ttpci/av7110.c index 3d20719..abf6b55 100644 --- a/drivers/media/dvb/ttpci/av7110.c +++ b/drivers/media/dvb/ttpci/av7110.c @@ -991,7 +991,7 @@ static int av7110_start_feed(struct dvb_demux_feed *feed) if (feed->type == DMX_TYPE_TS) { if ((feed->ts_type & TS_DECODER) && - (feed->pes_type < DMX_TS_PES_OTHER)) { + (feed->pes_type <= DMX_TS_PES_PCR)) { switch (demux->dmx.frontend->source) { case DMX_MEMORY_FE: if (feed->ts_type & TS_DECODER) -- cgit v0.10.2 From dbea1880368071dfa97d5e6aa4a368e7d0146a85 Mon Sep 17 00:00:00 2001 From: Andrew Vincer Date: Tue, 8 Nov 2011 12:43:45 -0300 Subject: [media] rc: Fix input deadlock and transmit error in redrat3 driver Fixed submit urb logic so hardware doesn't hang trying to transmit signal data Removed unneeded enable/disable detector commands in redrat3_transmit_ir (the hardware does this anyway) and converted arguments to unsigned as per 5588dc2 Signed-off-by: Andrew Vincer Cc: Jarod Wilson Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/rc/redrat3.c b/drivers/media/rc/redrat3.c index 61287fc..9bff23c 100644 --- a/drivers/media/rc/redrat3.c +++ b/drivers/media/rc/redrat3.c @@ -286,12 +286,6 @@ static void redrat3_issue_async(struct redrat3_dev *rr3) rr3_ftr(rr3->dev, "Entering %s\n", __func__); - if (!rr3->det_enabled) { - dev_warn(rr3->dev, "not issuing async read, " - "detector not enabled\n"); - return; - } - memset(rr3->bulk_in_buf, 0, rr3->ep_in->wMaxPacketSize); res = usb_submit_urb(rr3->read_urb, GFP_ATOMIC); if (res) @@ -827,6 +821,7 @@ out: static void redrat3_handle_async(struct urb *urb, struct pt_regs *regs) { struct redrat3_dev *rr3; + int ret; if (!urb) return; @@ -840,15 +835,13 @@ static void redrat3_handle_async(struct urb *urb, struct pt_regs *regs) rr3_ftr(rr3->dev, "Entering %s\n", __func__); - if (!rr3->det_enabled) { - rr3_dbg(rr3->dev, "received a read callback but detector " - "disabled - ignoring\n"); - return; - } - switch (urb->status) { case 0: - redrat3_get_ir_data(rr3, urb->actual_length); + ret = redrat3_get_ir_data(rr3, urb->actual_length); + if (!ret) { + /* no error, prepare to read more */ + redrat3_issue_async(rr3); + } break; case -ECONNRESET: @@ -865,11 +858,6 @@ static void redrat3_handle_async(struct urb *urb, struct pt_regs *regs) rr3->pkttype = 0; break; } - - if (!rr3->transmitting) - redrat3_issue_async(rr3); - else - rr3_dbg(rr3->dev, "IR transmit in progress\n"); } static void redrat3_write_bulk_callback(struct urb *urb, struct pt_regs *regs) @@ -896,21 +884,24 @@ static u16 mod_freq_to_val(unsigned int mod_freq) return (u16)(65536 - (mult / mod_freq)); } -static int redrat3_set_tx_carrier(struct rc_dev *dev, u32 carrier) +static int redrat3_set_tx_carrier(struct rc_dev *rcdev, u32 carrier) { - struct redrat3_dev *rr3 = dev->priv; + struct redrat3_dev *rr3 = rcdev->priv; + struct device *dev = rr3->dev; + rr3_dbg(dev, "Setting modulation frequency to %u", carrier); rr3->carrier = carrier; return carrier; } -static int redrat3_transmit_ir(struct rc_dev *rcdev, int *txbuf, u32 n) +static int redrat3_transmit_ir(struct rc_dev *rcdev, unsigned *txbuf, + unsigned count) { struct redrat3_dev *rr3 = rcdev->priv; struct device *dev = rr3->dev; struct redrat3_signal_header header; - int i, j, count, ret, ret_len, offset; + int i, j, ret, ret_len, offset; int lencheck, cur_sample_len, pipe; char *buffer = NULL, *sigdata = NULL; int *sample_lens = NULL; @@ -928,20 +919,13 @@ static int redrat3_transmit_ir(struct rc_dev *rcdev, int *txbuf, u32 n) return -EAGAIN; } - count = n / sizeof(int); if (count > (RR3_DRIVER_MAXLENS * 2)) return -EINVAL; + /* rr3 will disable rc detector on transmit */ + rr3->det_enabled = false; rr3->transmitting = true; - redrat3_disable_detector(rr3); - - if (rr3->det_enabled) { - dev_err(dev, "%s: cannot tx while rx is enabled\n", __func__); - ret = -EIO; - goto out; - } - sample_lens = kzalloc(sizeof(int) * RR3_DRIVER_MAXLENS, GFP_KERNEL); if (!sample_lens) { ret = -ENOMEM; @@ -1055,7 +1039,7 @@ static int redrat3_transmit_ir(struct rc_dev *rcdev, int *txbuf, u32 n) if (ret < 0) dev_err(dev, "Error: control msg send failed, rc %d\n", ret); else - ret = n; + ret = count; out: kfree(sample_lens); @@ -1063,8 +1047,8 @@ out: kfree(sigdata); rr3->transmitting = false; - - redrat3_enable_detector(rr3); + /* rr3 re-enables rc detector because it was enabled before */ + rr3->det_enabled = true; return ret; } -- cgit v0.10.2 From 1ec9a35e1cfaff6983977b5db4ed2f81a0e63920 Mon Sep 17 00:00:00 2001 From: Sylwester Nawrocki Date: Tue, 8 Nov 2011 19:16:04 -0300 Subject: [media] staging: as102: Add missing function argument Add missing dev argument in dev_err() call to correct an error introduced in commit 880102898f19cf9f9ba36dc9d838b5476645ce00 Signed-off-by: Sylwester Nawrocki Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/staging/media/as102/as102_drv.c b/drivers/staging/media/as102/as102_drv.c index b8adfd2..beacb2c 100644 --- a/drivers/staging/media/as102/as102_drv.c +++ b/drivers/staging/media/as102/as102_drv.c @@ -220,7 +220,7 @@ int as102_dvb_register(struct as102_dev_t *as102_dev) ret = dvb_dmx_init(&as102_dev->dvb_dmx); if (ret < 0) { - dev_err("%s: dvb_dmx_init() failed: %d\n", __func__, ret); + dev_err(dev, "%s: dvb_dmx_init() failed: %d\n", __func__, ret); goto edmxinit; } -- cgit v0.10.2 From 8503232f2e9604d844d8f52ddea2e55ccc6c38f6 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 24 Nov 2011 15:01:45 -0200 Subject: [media] em28xx: Fix a few warnings due to HVR-930C addition MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit drivers/media/video/em28xx/em28xx-cards.c:339:30: warning: ‘hauppauge_930c_gpio’ defined but not used [-Wunused-variable] drivers/media/video/em28xx/em28xx-dvb.c: In function ‘em28xx_dvb_init’: drivers/media/video/em28xx/em28xx-dvb.c:886:3: warning: ISO C90 forbids mixed declarations and code [-Wdeclaration-after-statement] Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c index f63a715..5b0336b 100644 --- a/drivers/media/video/em28xx/em28xx-cards.c +++ b/drivers/media/video/em28xx/em28xx-cards.c @@ -336,6 +336,7 @@ static struct em28xx_reg_seq pctv_460e[] = { { -1, -1, -1, -1}, }; +#if 0 static struct em28xx_reg_seq hauppauge_930c_gpio[] = { {EM2874_R80_GPIO, 0x6f, 0xff, 10}, {EM2874_R80_GPIO, 0x4f, 0xff, 10}, /* xc5000 reset */ @@ -344,7 +345,6 @@ static struct em28xx_reg_seq hauppauge_930c_gpio[] = { { -1, -1, -1, -1}, }; -#if 0 static struct em28xx_reg_seq hauppauge_930c_digital[] = { {EM2874_R80_GPIO, 0xf6, 0xff, 10}, {EM2874_R80_GPIO, 0xe6, 0xff, 100}, diff --git a/drivers/media/video/em28xx/em28xx-dvb.c b/drivers/media/video/em28xx/em28xx-dvb.c index 55a9008..ea2208e 100644 --- a/drivers/media/video/em28xx/em28xx-dvb.c +++ b/drivers/media/video/em28xx/em28xx-dvb.c @@ -864,6 +864,8 @@ static int em28xx_dvb_init(struct em28xx *dev) } break; case EM2884_BOARD_HAUPPAUGE_WINTV_HVR_930C: + { + struct xc5000_config cfg; hauppauge_hvr930c_init(dev); dvb->dont_attach_fe1 = 1; @@ -883,7 +885,6 @@ static int em28xx_dvb_init(struct em28xx *dev) dvb->fe[1]->id = 1; /* Attach xc5000 */ - struct xc5000_config cfg; memset(&cfg, 0, sizeof(cfg)); cfg.i2c_address = 0x61; cfg.if_khz = 4000; @@ -906,6 +907,7 @@ static int em28xx_dvb_init(struct em28xx *dev) sizeof(dvb->fe[0]->ops.tuner_ops)); break; + } case EM2884_BOARD_TERRATEC_H5: terratec_h5_init(dev); -- cgit v0.10.2 From 4a5006f68d6b336564eb1e4cbb1f66d234958889 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 24 Nov 2011 15:04:18 -0200 Subject: [media] firedtv-avc: Fix compilation warnings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit drivers/media/dvb/firewire/firedtv-avc.c: In function ‘avc_tuner_tuneqpsk’: drivers/media/dvb/firewire/firedtv-avc.c:394:4: warning: enumeration value ‘ROLLOFF_15’ not handled in switch [-Wswitch] drivers/media/dvb/firewire/firedtv-avc.c:394:4: warning: enumeration value ‘ROLLOFF_13’ not handled in switch [-Wswitch] Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/dvb/firewire/firedtv-avc.c b/drivers/media/dvb/firewire/firedtv-avc.c index 489ae82..9debf0f 100644 --- a/drivers/media/dvb/firewire/firedtv-avc.c +++ b/drivers/media/dvb/firewire/firedtv-avc.c @@ -392,10 +392,11 @@ static int avc_tuner_tuneqpsk(struct firedtv *fdtv, default: c->operand[13] = 0x2; break; } switch (fdtv->fe.dtv_property_cache.rolloff) { - case ROLLOFF_AUTO: c->operand[14] = 0x2; break; case ROLLOFF_35: c->operand[14] = 0x2; break; case ROLLOFF_20: c->operand[14] = 0x0; break; case ROLLOFF_25: c->operand[14] = 0x1; break; + case ROLLOFF_AUTO: + default: c->operand[14] = 0x2; break; /* case ROLLOFF_NONE: c->operand[14] = 0xff; break; */ } switch (fdtv->fe.dtv_property_cache.pilot) { -- cgit v0.10.2 From a824f0f445ad2c86a40b4bf43acba26dfd0a98a9 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 9 Nov 2011 13:27:53 -0300 Subject: [media] video: Drop undue references to i2c-algo-bit There's one comment that has been copied from bttv to many other media/video drivers: /* init + register i2c algo-bit adapter */ Meanwhile, many drivers use hardware I2C implementations instead of relying on i2c-algo-bit, so this comment is misleading. Remove the reference to "algo-bit" from all drivers, to avoid any confusion. This is the best way to ensure that the comments won't go out of sync again. Anyone interested in the implementation details would rather look at the code itself. Signed-off-by: Jean Delvare Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/au0828/au0828-i2c.c b/drivers/media/video/au0828/au0828-i2c.c index cbdb65c..05c299f 100644 --- a/drivers/media/video/au0828/au0828-i2c.c +++ b/drivers/media/video/au0828/au0828-i2c.c @@ -348,7 +348,7 @@ static void do_i2c_scan(char *name, struct i2c_client *c) } } -/* init + register i2c algo-bit adapter */ +/* init + register i2c adapter */ int au0828_i2c_register(struct au0828_dev *dev) { dprintk(1, "%s()\n", __func__); diff --git a/drivers/media/video/bt8xx/bttv-i2c.c b/drivers/media/video/bt8xx/bttv-i2c.c index e3952af..580c8e6 100644 --- a/drivers/media/video/bt8xx/bttv-i2c.c +++ b/drivers/media/video/bt8xx/bttv-i2c.c @@ -346,7 +346,7 @@ static void do_i2c_scan(char *name, struct i2c_client *c) } } -/* init + register i2c algo-bit adapter */ +/* init + register i2c adapter */ int __devinit init_bttv_i2c(struct bttv *btv) { strlcpy(btv->i2c_client.name, "bttv internal", I2C_NAME_SIZE); diff --git a/drivers/media/video/cx18/cx18-i2c.c b/drivers/media/video/cx18/cx18-i2c.c index 040aaa8..51609d5 100644 --- a/drivers/media/video/cx18/cx18-i2c.c +++ b/drivers/media/video/cx18/cx18-i2c.c @@ -232,7 +232,7 @@ static struct i2c_algo_bit_data cx18_i2c_algo_template = { .timeout = CX18_ALGO_BIT_TIMEOUT*HZ /* jiffies */ }; -/* init + register i2c algo-bit adapter */ +/* init + register i2c adapter */ int init_cx18_i2c(struct cx18 *cx) { int i, err; diff --git a/drivers/media/video/cx18/cx18-i2c.h b/drivers/media/video/cx18/cx18-i2c.h index bdfd192..1180fdc 100644 --- a/drivers/media/video/cx18/cx18-i2c.h +++ b/drivers/media/video/cx18/cx18-i2c.h @@ -24,6 +24,6 @@ int cx18_i2c_register(struct cx18 *cx, unsigned idx); struct v4l2_subdev *cx18_find_hw(struct cx18 *cx, u32 hw); -/* init + register i2c algo-bit adapter */ +/* init + register i2c adapter */ int init_cx18_i2c(struct cx18 *cx); void exit_cx18_i2c(struct cx18 *cx); diff --git a/drivers/media/video/cx23885/cx23885-i2c.c b/drivers/media/video/cx23885/cx23885-i2c.c index 0ff7a9e..be1e21d 100644 --- a/drivers/media/video/cx23885/cx23885-i2c.c +++ b/drivers/media/video/cx23885/cx23885-i2c.c @@ -309,7 +309,7 @@ static void do_i2c_scan(char *name, struct i2c_client *c) } } -/* init + register i2c algo-bit adapter */ +/* init + register i2c adapter */ int cx23885_i2c_register(struct cx23885_i2c *bus) { struct cx23885_dev *dev = bus->dev; diff --git a/drivers/media/video/cx25821/cx25821-i2c.c b/drivers/media/video/cx25821/cx25821-i2c.c index 4d3d0ce..77fa8eb 100644 --- a/drivers/media/video/cx25821/cx25821-i2c.c +++ b/drivers/media/video/cx25821/cx25821-i2c.c @@ -300,7 +300,7 @@ static struct i2c_client cx25821_i2c_client_template = { .name = "cx25821 internal", }; -/* init + register i2c algo-bit adapter */ +/* init + register i2c adapter */ int cx25821_i2c_register(struct cx25821_i2c *bus) { struct cx25821_dev *dev = bus->dev; diff --git a/drivers/media/video/cx88/cx88-i2c.c b/drivers/media/video/cx88/cx88-i2c.c index a1fe0ab..de0f1af 100644 --- a/drivers/media/video/cx88/cx88-i2c.c +++ b/drivers/media/video/cx88/cx88-i2c.c @@ -132,7 +132,7 @@ static void do_i2c_scan(const char *name, struct i2c_client *c) } } -/* init + register i2c algo-bit adapter */ +/* init + register i2c adapter */ int cx88_i2c_init(struct cx88_core *core, struct pci_dev *pci) { /* Prevents usage of invalid delay values */ diff --git a/drivers/media/video/ivtv/ivtv-i2c.h b/drivers/media/video/ivtv/ivtv-i2c.h index 9332920..7b9ec1c 100644 --- a/drivers/media/video/ivtv/ivtv-i2c.h +++ b/drivers/media/video/ivtv/ivtv-i2c.h @@ -25,7 +25,7 @@ struct i2c_client *ivtv_i2c_new_ir_legacy(struct ivtv *itv); int ivtv_i2c_register(struct ivtv *itv, unsigned idx); struct v4l2_subdev *ivtv_find_hw(struct ivtv *itv, u32 hw); -/* init + register i2c algo-bit adapter */ +/* init + register i2c adapter */ int init_ivtv_i2c(struct ivtv *itv); void exit_ivtv_i2c(struct ivtv *itv); -- cgit v0.10.2 From 8798875369ca5a1862c96425ab43b67ccbccccd0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alfredo=20Jes=C3=BAs=20Delaiti?= Date: Wed, 9 Nov 2011 15:13:00 -0300 Subject: [media] cx23885: add support for Mygica X8507 This patch supports card Mygica X8507 (analog part) This controller is a copy of driver card Mygica X8506 This patch depends on patch cx23885-alsa To do: FM, ISDB-t, remote control, audio for composite1, S-Video and video component. Signed-off-by: Alfredo J. Delaiti Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/cx23885/cx23885-cards.c b/drivers/media/video/cx23885/cx23885-cards.c index c3cf089..ac03c26 100644 --- a/drivers/media/video/cx23885/cx23885-cards.c +++ b/drivers/media/video/cx23885/cx23885-cards.c @@ -438,6 +438,36 @@ struct cx23885_board cx23885_boards[] = { .gpio0 = 0, } }, }, + [CX23885_BOARD_MYGICA_X8507] = { + .name = "Mygica X8507", + .tuner_type = TUNER_XC5000, + .tuner_addr = 0x61, + .tuner_bus = 1, + .porta = CX23885_ANALOG_VIDEO, + .input = { + { + .type = CX23885_VMUX_TELEVISION, + .vmux = CX25840_COMPOSITE2, + .amux = CX25840_AUDIO8, + }, + { + .type = CX23885_VMUX_COMPOSITE1, + .vmux = CX25840_COMPOSITE8, + }, + { + .type = CX23885_VMUX_SVIDEO, + .vmux = CX25840_SVIDEO_LUMA3 | + CX25840_SVIDEO_CHROMA4, + }, + { + .type = CX23885_VMUX_COMPONENT, + .vmux = CX25840_COMPONENT_ON | + CX25840_VIN1_CH1 | + CX25840_VIN6_CH2 | + CX25840_VIN7_CH3, + }, + }, + } }; const unsigned int cx23885_bcount = ARRAY_SIZE(cx23885_boards); @@ -637,6 +667,10 @@ struct cx23885_subid cx23885_subids[] = { .subvendor = 0x1b55, .subdevice = 0xe2e4, .card = CX23885_BOARD_NETUP_DUAL_DVB_T_C_CI_RF, + }, { + .subvendor = 0x14f1, + .subdevice = 0x8502, + .card = CX23885_BOARD_MYGICA_X8507, }, }; const unsigned int cx23885_idcount = ARRAY_SIZE(cx23885_subids); @@ -1068,6 +1102,7 @@ void cx23885_gpio_setup(struct cx23885_dev *dev) break; case CX23885_BOARD_MYGICA_X8506: case CX23885_BOARD_MAGICPRO_PROHDTVE2: + case CX23885_BOARD_MYGICA_X8507: /* GPIO-0 (0)Analog / (1)Digital TV */ /* GPIO-1 reset XC5000 */ /* GPIO-2 reset LGS8GL5 / LGS8G75 */ @@ -1468,6 +1503,7 @@ void cx23885_card_setup(struct cx23885_dev *dev) case CX23885_BOARD_GOTVIEW_X5_3D_HYBRID: case CX23885_BOARD_HAUPPAUGE_HVR1500: case CX23885_BOARD_MPX885: + case CX23885_BOARD_MYGICA_X8507: dev->sd_cx25840 = v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_bus[2].i2c_adap, "cx25840", 0x88 >> 1, NULL); diff --git a/drivers/media/video/cx23885/cx23885-video.c b/drivers/media/video/cx23885/cx23885-video.c index e730b92..7415524 100644 --- a/drivers/media/video/cx23885/cx23885-video.c +++ b/drivers/media/video/cx23885/cx23885-video.c @@ -492,7 +492,8 @@ static int cx23885_video_mux(struct cx23885_dev *dev, unsigned int input) dev->input = input; if (dev->board == CX23885_BOARD_MYGICA_X8506 || - dev->board == CX23885_BOARD_MAGICPRO_PROHDTVE2) { + dev->board == CX23885_BOARD_MAGICPRO_PROHDTVE2 || + dev->board == CX23885_BOARD_MYGICA_X8507) { /* Select Analog TV */ if (INPUT(input)->type == CX23885_VMUX_TELEVISION) cx23885_gpio_clear(dev, GPIO_0); diff --git a/drivers/media/video/cx23885/cx23885.h b/drivers/media/video/cx23885/cx23885.h index b49036f..519f40d 100644 --- a/drivers/media/video/cx23885/cx23885.h +++ b/drivers/media/video/cx23885/cx23885.h @@ -87,6 +87,7 @@ #define CX23885_BOARD_NETUP_DUAL_DVB_T_C_CI_RF 30 #define CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H_XC4000 31 #define CX23885_BOARD_MPX885 32 +#define CX23885_BOARD_MYGICA_X8507 33 #define GPIO_0 0x00000001 #define GPIO_1 0x00000002 -- cgit v0.10.2 From 4da621b69e5c0ac139c5240230c21da74253d2b9 Mon Sep 17 00:00:00 2001 From: Heungjun Kim Date: Fri, 11 Nov 2011 08:05:33 -0300 Subject: [media] MAINTAINERS: Add m5mols driver maintainers Add the maintainers for the m5mols driver Signed-off-by: HeungJun, Kim Signed-off-by: Kyungmin Park Acked-by: Sylwester Nawrocki Signed-off-by: Mauro Carvalho Chehab diff --git a/MAINTAINERS b/MAINTAINERS index 071a996..879b02c 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2836,6 +2836,14 @@ L: platform-driver-x86@vger.kernel.org S: Maintained F: drivers/platform/x86/fujitsu-laptop.c +FUJITSU M-5MO LS CAMERA ISP DRIVER +M: Kyungmin Park +M: Heungjun Kim +L: linux-media@vger.kernel.org +S: Maintained +F: drivers/media/video/m5mols/ +F: include/media/m5mols.h + FUSE: FILESYSTEM IN USERSPACE M: Miklos Szeredi L: fuse-devel@lists.sourceforge.net -- cgit v0.10.2 From 022568f05891b6a371f0fdbab9abccf9239276a2 Mon Sep 17 00:00:00 2001 From: Paul Bolle Date: Sun, 13 Nov 2011 12:16:40 -0300 Subject: [media] Fix typos in VIDEO_CX231XX_DVB Kconfig entry Commit ede676c72d ("[...] add digital support for PV SBTVD hybrid") added "select MEDIA_TUNER_NXP18271" to the VIDEO_CX231XX_DVB Kconfig entry. But there's no Kconfig symbol MEDIA_TUNER_NXP18271. That should have been MEDIA_TUNER_TDA18271. (The code added in that commit uses tda18271_attach, which is only available if MEDIA_TUNER_TDA18271 is set.) The selects of MEDIA_TUNER_XC5000 and MEDIA_TUNER_TDA18271 should only be done if MEDIA_TUNER_CUSTOMISE isn't set. Signed-off-by: Paul Bolle Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/cx231xx/Kconfig b/drivers/media/video/cx231xx/Kconfig index ae85a7a..c74ce9e 100644 --- a/drivers/media/video/cx231xx/Kconfig +++ b/drivers/media/video/cx231xx/Kconfig @@ -42,8 +42,8 @@ config VIDEO_CX231XX_DVB tristate "DVB/ATSC Support for Cx231xx based TV cards" depends on VIDEO_CX231XX && DVB_CORE select VIDEOBUF_DVB - select MEDIA_TUNER_XC5000 if !DVB_FE_CUSTOMISE - select MEDIA_TUNER_NXP18271 if !DVB_FE_CUSTOMISE + select MEDIA_TUNER_XC5000 if !MEDIA_TUNER_CUSTOMISE + select MEDIA_TUNER_TDA18271 if !MEDIA_TUNER_CUSTOMISE select DVB_MB86A20S if !DVB_FE_CUSTOMISE ---help--- -- cgit v0.10.2 From 522fdf731946301ab7a5ecf854cbe89462397b81 Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Sun, 13 Nov 2011 00:19:56 -0300 Subject: [media] tda18218: implement .get_if_frequency() Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/common/tuners/tda18218.c b/drivers/media/common/tuners/tda18218.c index aacfe23..1c86595 100644 --- a/drivers/media/common/tuners/tda18218.c +++ b/drivers/media/common/tuners/tda18218.c @@ -141,19 +141,21 @@ static int tda18218_set_params(struct dvb_frontend *fe, switch (params->u.ofdm.bandwidth) { case BANDWIDTH_6_MHZ: LP_Fc = 0; - LO_Frac = params->frequency + 4000000; + priv->if_frequency = 4000000; break; case BANDWIDTH_7_MHZ: LP_Fc = 1; - LO_Frac = params->frequency + 3500000; + priv->if_frequency = 3500000; break; case BANDWIDTH_8_MHZ: default: LP_Fc = 2; - LO_Frac = params->frequency + 4000000; + priv->if_frequency = 4000000; break; } + LO_Frac = params->frequency + priv->if_frequency; + /* band-pass filter */ if (LO_Frac < 188000000) BP_Filter = 3; @@ -206,6 +208,14 @@ error: return ret; } +static int tda18218_get_if_frequency(struct dvb_frontend *fe, u32 *frequency) +{ + struct tda18218_priv *priv = fe->tuner_priv; + *frequency = priv->if_frequency; + dbg("%s: if=%d", __func__, *frequency); + return 0; +} + static int tda18218_sleep(struct dvb_frontend *fe) { struct tda18218_priv *priv = fe->tuner_priv; @@ -268,6 +278,8 @@ static const struct dvb_tuner_ops tda18218_tuner_ops = { .sleep = tda18218_sleep, .set_params = tda18218_set_params, + + .get_if_frequency = tda18218_get_if_frequency, }; struct dvb_frontend *tda18218_attach(struct dvb_frontend *fe, diff --git a/drivers/media/common/tuners/tda18218_priv.h b/drivers/media/common/tuners/tda18218_priv.h index 904e536..dc52b72 100644 --- a/drivers/media/common/tuners/tda18218_priv.h +++ b/drivers/media/common/tuners/tda18218_priv.h @@ -100,6 +100,8 @@ struct tda18218_priv { struct tda18218_config *cfg; struct i2c_adapter *i2c; + u32 if_frequency; + u8 regs[TDA18218_NUM_REGS]; }; -- cgit v0.10.2 From 6d42b218b43f300d0787df7984c8f789de24c6e7 Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Sun, 13 Nov 2011 00:26:17 -0300 Subject: [media] af9013: use .get_if_frequency() when possible Get IF frequency from tuner if tuner provides it. Remove TDA18271 and TDA18218 IF frequency hacks since both tuners provides .get_if_frequency(). Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/dvb/frontends/af9013.c b/drivers/media/dvb/frontends/af9013.c index 345311c..f4276e4 100644 --- a/drivers/media/dvb/frontends/af9013.c +++ b/drivers/media/dvb/frontends/af9013.c @@ -303,7 +303,8 @@ error: return ret; } -static int af9013_set_freq_ctrl(struct af9013_state *state, fe_bandwidth_t bw) +static int af9013_set_freq_ctrl(struct af9013_state *state, + struct dvb_frontend *fe) { int ret; u16 addr; @@ -324,37 +325,13 @@ static int af9013_set_freq_ctrl(struct af9013_state *state, fe_bandwidth_t bw) bfs_spec_inv = state->config.rf_spec_inv ? 1 : -1; } - adc_freq = state->config.adc_clock * 1000; - if_sample_freq = state->config.tuner_if * 1000; + adc_freq = state->config.adc_clock * 1000; - /* TDA18271 uses different sampling freq for every bw */ - if (state->config.tuner == AF9013_TUNER_TDA18271) { - switch (bw) { - case BANDWIDTH_6_MHZ: - if_sample_freq = 3300000; /* 3.3 MHz */ - break; - case BANDWIDTH_7_MHZ: - if_sample_freq = 3500000; /* 3.5 MHz */ - break; - case BANDWIDTH_8_MHZ: - default: - if_sample_freq = 4000000; /* 4.0 MHz */ - break; - } - } else if (state->config.tuner == AF9013_TUNER_TDA18218) { - switch (bw) { - case BANDWIDTH_6_MHZ: - if_sample_freq = 3000000; /* 3 MHz */ - break; - case BANDWIDTH_7_MHZ: - if_sample_freq = 3500000; /* 3.5 MHz */ - break; - case BANDWIDTH_8_MHZ: - default: - if_sample_freq = 4000000; /* 4 MHz */ - break; - } - } + /* get used IF frequency */ + if (fe->ops.tuner_ops.get_if_frequency) + fe->ops.tuner_ops.get_if_frequency(fe, &if_sample_freq); + else + if_sample_freq = state->config.tuner_if * 1000; while (if_sample_freq > (adc_freq / 2)) if_sample_freq = if_sample_freq - adc_freq; @@ -639,7 +616,7 @@ static int af9013_set_frontend(struct dvb_frontend *fe, goto error; /* program frequency control */ - ret = af9013_set_freq_ctrl(state, params->u.ofdm.bandwidth); + ret = af9013_set_freq_ctrl(state, fe); if (ret) goto error; -- cgit v0.10.2 From 055327c55a7b74b25bf3e178da353982e6eef487 Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Sun, 13 Nov 2011 00:44:57 -0300 Subject: [media] mt2060: implement .get_if_frequency() Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/common/tuners/mt2060.c b/drivers/media/common/tuners/mt2060.c index 2d0e768..2ecaa53 100644 --- a/drivers/media/common/tuners/mt2060.c +++ b/drivers/media/common/tuners/mt2060.c @@ -300,6 +300,12 @@ static int mt2060_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth) return 0; } +static int mt2060_get_if_frequency(struct dvb_frontend *fe, u32 *frequency) +{ + *frequency = IF2 * 1000; + return 0; +} + static int mt2060_init(struct dvb_frontend *fe) { struct mt2060_priv *priv = fe->tuner_priv; @@ -356,7 +362,8 @@ static const struct dvb_tuner_ops mt2060_tuner_ops = { .set_params = mt2060_set_params, .get_frequency = mt2060_get_frequency, - .get_bandwidth = mt2060_get_bandwidth + .get_bandwidth = mt2060_get_bandwidth, + .get_if_frequency = mt2060_get_if_frequency, }; /* This functions tries to identify a MT2060 tuner by reading the PART/REV register. This is hasty. */ -- cgit v0.10.2 From ed9405140e1ad1602352d525afede193ebfd67d7 Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Sun, 13 Nov 2011 01:07:42 -0300 Subject: [media] qt1010: implement .get_if_frequency() Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/common/tuners/qt1010.c b/drivers/media/common/tuners/qt1010.c index 9f5dba2..cd461c2 100644 --- a/drivers/media/common/tuners/qt1010.c +++ b/drivers/media/common/tuners/qt1010.c @@ -423,6 +423,12 @@ static int qt1010_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth) return 0; } +static int qt1010_get_if_frequency(struct dvb_frontend *fe, u32 *frequency) +{ + *frequency = 36125000; + return 0; +} + static const struct dvb_tuner_ops qt1010_tuner_ops = { .info = { .name = "Quantek QT1010", @@ -437,7 +443,8 @@ static const struct dvb_tuner_ops qt1010_tuner_ops = { .set_params = qt1010_set_params, .get_frequency = qt1010_get_frequency, - .get_bandwidth = qt1010_get_bandwidth + .get_bandwidth = qt1010_get_bandwidth, + .get_if_frequency = qt1010_get_if_frequency, }; struct dvb_frontend * qt1010_attach(struct dvb_frontend *fe, -- cgit v0.10.2 From 835bf82ce4b64e280ca6c4da67c819a1065693bc Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Sun, 13 Nov 2011 11:20:08 -0300 Subject: [media] tda18212: implement .get_if_frequency() Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/common/tuners/tda18212.c b/drivers/media/common/tuners/tda18212.c index 6374a1e..b1750d2 100644 --- a/drivers/media/common/tuners/tda18212.c +++ b/drivers/media/common/tuners/tda18212.c @@ -25,6 +25,8 @@ struct tda18212_priv { struct tda18212_config *cfg; struct i2c_adapter *i2c; + + u32 if_frequency; }; #define dbg(fmt, arg...) \ @@ -235,6 +237,9 @@ static int tda18212_set_params(struct dvb_frontend *fe, if (ret) goto error; + /* actual IF rounded as it is on register */ + priv->if_frequency = buf[3] * 50 * 1000; + exit: if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */ @@ -246,6 +251,15 @@ error: goto exit; } +static int tda18212_get_if_frequency(struct dvb_frontend *fe, u32 *frequency) +{ + struct tda18212_priv *priv = fe->tuner_priv; + + *frequency = priv->if_frequency; + + return 0; +} + static int tda18212_release(struct dvb_frontend *fe) { kfree(fe->tuner_priv); @@ -265,6 +279,7 @@ static const struct dvb_tuner_ops tda18212_tuner_ops = { .release = tda18212_release, .set_params = tda18212_set_params, + .get_if_frequency = tda18212_get_if_frequency, }; struct dvb_frontend *tda18212_attach(struct dvb_frontend *fe, -- cgit v0.10.2 From 8cffcc78996c25a04423e294faa1bb5bba3e420e Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Sun, 13 Nov 2011 11:22:58 -0300 Subject: [media] tda18212: round IF frequency to close hardware value Chip configures IF frequency resolution of 50 kHz. Round it nearest. Off-by 50 kHz is almost nothing in real life... Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/common/tuners/tda18212.c b/drivers/media/common/tuners/tda18212.c index b1750d2..f52282e 100644 --- a/drivers/media/common/tuners/tda18212.c +++ b/drivers/media/common/tuners/tda18212.c @@ -227,7 +227,7 @@ static int tda18212_set_params(struct dvb_frontend *fe, buf[0] = 0x02; buf[1] = bw_params[i][1]; buf[2] = 0x03; /* default value */ - buf[3] = if_khz / 50; + buf[3] = DIV_ROUND_CLOSEST(if_khz, 50); buf[4] = ((c->frequency / 1000) >> 16) & 0xff; buf[5] = ((c->frequency / 1000) >> 8) & 0xff; buf[6] = ((c->frequency / 1000) >> 0) & 0xff; -- cgit v0.10.2 From fda23faaff3b28a987c22da5f3a17b9f3d4acef8 Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Sun, 13 Nov 2011 14:41:25 -0300 Subject: [media] cxd2820r: switch to .get_if_frequency() All tuners used with cxd2820r offers IF frequency so switch that. Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/dvb/dvb-usb/anysee.c b/drivers/media/dvb/dvb-usb/anysee.c index c64eb56..df46015 100644 --- a/drivers/media/dvb/dvb-usb/anysee.c +++ b/drivers/media/dvb/dvb-usb/anysee.c @@ -366,13 +366,6 @@ static struct isl6423_config anysee_isl6423_config = { static struct cxd2820r_config anysee_cxd2820r_config = { .i2c_address = 0x6d, /* (0xda >> 1) */ .ts_mode = 0x38, - .if_dvbt_6 = 3550, - .if_dvbt_7 = 3700, - .if_dvbt_8 = 4150, - .if_dvbt2_6 = 3250, - .if_dvbt2_7 = 4000, - .if_dvbt2_8 = 4000, - .if_dvbc = 5000, }; /* diff --git a/drivers/media/dvb/frontends/cxd2820r.h b/drivers/media/dvb/frontends/cxd2820r.h index 03cab7b..cf0f546 100644 --- a/drivers/media/dvb/frontends/cxd2820r.h +++ b/drivers/media/dvb/frontends/cxd2820r.h @@ -63,19 +63,6 @@ struct cxd2820r_config { */ bool spec_inv; - /* IFs for all used modes. - * Default: none, must set - * Values: - */ - u16 if_dvbt_6; - u16 if_dvbt_7; - u16 if_dvbt_8; - u16 if_dvbt2_5; - u16 if_dvbt2_6; - u16 if_dvbt2_7; - u16 if_dvbt2_8; - u16 if_dvbc; - /* GPIOs for all used modes. * Default: none, disabled * Values: diff --git a/drivers/media/dvb/frontends/cxd2820r_c.c b/drivers/media/dvb/frontends/cxd2820r_c.c index b85f501..c412877 100644 --- a/drivers/media/dvb/frontends/cxd2820r_c.c +++ b/drivers/media/dvb/frontends/cxd2820r_c.c @@ -28,6 +28,7 @@ int cxd2820r_set_frontend_c(struct dvb_frontend *fe, struct dtv_frontend_properties *c = &fe->dtv_property_cache; int ret, i; u8 buf[2]; + u32 if_freq; u16 if_ctl; u64 num; struct reg_val_mask tab[] = { @@ -70,7 +71,17 @@ int cxd2820r_set_frontend_c(struct dvb_frontend *fe, priv->delivery_system = SYS_DVBC_ANNEX_AC; priv->ber_running = 0; /* tune stops BER counter */ - num = priv->cfg.if_dvbc; + /* program IF frequency */ + if (fe->ops.tuner_ops.get_if_frequency) { + ret = fe->ops.tuner_ops.get_if_frequency(fe, &if_freq); + if (ret) + goto error; + } else + if_freq = 0; + + dbg("%s: if_freq=%d", __func__, if_freq); + + num = if_freq / 1000; /* Hz => kHz */ num *= 0x4000; if_ctl = cxd2820r_div_u64_round_closest(num, 41000); buf[0] = (if_ctl >> 8) & 0x3f; diff --git a/drivers/media/dvb/frontends/cxd2820r_t.c b/drivers/media/dvb/frontends/cxd2820r_t.c index a04f9c8..86e17e6 100644 --- a/drivers/media/dvb/frontends/cxd2820r_t.c +++ b/drivers/media/dvb/frontends/cxd2820r_t.c @@ -27,7 +27,7 @@ int cxd2820r_set_frontend_t(struct dvb_frontend *fe, struct cxd2820r_priv *priv = fe->demodulator_priv; struct dtv_frontend_properties *c = &fe->dtv_property_cache; int ret, i; - u32 if_khz, if_ctl; + u32 if_freq, if_ctl; u64 num; u8 buf[3], bw_param; u8 bw_params1[][5] = { @@ -80,17 +80,14 @@ int cxd2820r_set_frontend_t(struct dvb_frontend *fe, switch (c->bandwidth_hz) { case 6000000: - if_khz = priv->cfg.if_dvbt_6; i = 0; bw_param = 2; break; case 7000000: - if_khz = priv->cfg.if_dvbt_7; i = 1; bw_param = 1; break; case 8000000: - if_khz = priv->cfg.if_dvbt_8; i = 2; bw_param = 0; break; @@ -98,7 +95,17 @@ int cxd2820r_set_frontend_t(struct dvb_frontend *fe, return -EINVAL; } - num = if_khz; + /* program IF frequency */ + if (fe->ops.tuner_ops.get_if_frequency) { + ret = fe->ops.tuner_ops.get_if_frequency(fe, &if_freq); + if (ret) + goto error; + } else + if_freq = 0; + + dbg("%s: if_freq=%d", __func__, if_freq); + + num = if_freq / 1000; /* Hz => kHz */ num *= 0x1000000; if_ctl = cxd2820r_div_u64_round_closest(num, 41000); buf[0] = ((if_ctl >> 16) & 0xff); diff --git a/drivers/media/dvb/frontends/cxd2820r_t2.c b/drivers/media/dvb/frontends/cxd2820r_t2.c index 6548588..8635b07 100644 --- a/drivers/media/dvb/frontends/cxd2820r_t2.c +++ b/drivers/media/dvb/frontends/cxd2820r_t2.c @@ -27,7 +27,7 @@ int cxd2820r_set_frontend_t2(struct dvb_frontend *fe, struct cxd2820r_priv *priv = fe->demodulator_priv; struct dtv_frontend_properties *c = &fe->dtv_property_cache; int ret, i; - u32 if_khz, if_ctl; + u32 if_freq, if_ctl; u64 num; u8 buf[3], bw_param; u8 bw_params1[][5] = { @@ -93,22 +93,18 @@ int cxd2820r_set_frontend_t2(struct dvb_frontend *fe, switch (c->bandwidth_hz) { case 5000000: - if_khz = priv->cfg.if_dvbt2_5; i = 0; bw_param = 3; break; case 6000000: - if_khz = priv->cfg.if_dvbt2_6; i = 1; bw_param = 2; break; case 7000000: - if_khz = priv->cfg.if_dvbt2_7; i = 2; bw_param = 1; break; case 8000000: - if_khz = priv->cfg.if_dvbt2_8; i = 3; bw_param = 0; break; @@ -116,7 +112,17 @@ int cxd2820r_set_frontend_t2(struct dvb_frontend *fe, return -EINVAL; } - num = if_khz; + /* program IF frequency */ + if (fe->ops.tuner_ops.get_if_frequency) { + ret = fe->ops.tuner_ops.get_if_frequency(fe, &if_freq); + if (ret) + goto error; + } else + if_freq = 0; + + dbg("%s: if_freq=%d", __func__, if_freq); + + num = if_freq / 1000; /* Hz => kHz */ num *= 0x1000000; if_ctl = cxd2820r_div_u64_round_closest(num, 41000); buf[0] = ((if_ctl >> 16) & 0xff); diff --git a/drivers/media/video/em28xx/em28xx-dvb.c b/drivers/media/video/em28xx/em28xx-dvb.c index ea2208e..eb41e25 100644 --- a/drivers/media/video/em28xx/em28xx-dvb.c +++ b/drivers/media/video/em28xx/em28xx-dvb.c @@ -500,13 +500,6 @@ static struct tda10023_config em28xx_tda10023_config = { static struct cxd2820r_config em28xx_cxd2820r_config = { .i2c_address = (0xd8 >> 1), .ts_mode = CXD2820R_TS_SERIAL, - .if_dvbt_6 = 3300, - .if_dvbt_7 = 3500, - .if_dvbt_8 = 4000, - .if_dvbt2_6 = 3300, - .if_dvbt2_7 = 3500, - .if_dvbt2_8 = 4000, - .if_dvbc = 5000, /* enable LNA for DVB-T2 and DVB-C */ .gpio_dvbt2[0] = CXD2820R_GPIO_E | CXD2820R_GPIO_O | CXD2820R_GPIO_L, -- cgit v0.10.2 From 13d723ba98545c451bb40711e718087d28985b0f Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Sun, 13 Nov 2011 15:21:58 -0300 Subject: [media] cxd2820r: check bandwidth earlier for DVB-T/T2 It is param that could be potentially unsupported and due to that it is good idea to check it very first. Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/dvb/frontends/cxd2820r_t.c b/drivers/media/dvb/frontends/cxd2820r_t.c index 86e17e6..b1450ac 100644 --- a/drivers/media/dvb/frontends/cxd2820r_t.c +++ b/drivers/media/dvb/frontends/cxd2820r_t.c @@ -26,7 +26,7 @@ int cxd2820r_set_frontend_t(struct dvb_frontend *fe, { struct cxd2820r_priv *priv = fe->demodulator_priv; struct dtv_frontend_properties *c = &fe->dtv_property_cache; - int ret, i; + int ret, i, bw_i; u32 if_freq, if_ctl; u64 num; u8 buf[3], bw_param; @@ -57,6 +57,23 @@ int cxd2820r_set_frontend_t(struct dvb_frontend *fe, dbg("%s: RF=%d BW=%d", __func__, c->frequency, c->bandwidth_hz); + switch (c->bandwidth_hz) { + case 6000000: + bw_i = 0; + bw_param = 2; + break; + case 7000000: + bw_i = 1; + bw_param = 1; + break; + case 8000000: + bw_i = 2; + bw_param = 0; + break; + default: + return -EINVAL; + } + /* update GPIOs */ ret = cxd2820r_gpio(fe); if (ret) @@ -78,23 +95,6 @@ int cxd2820r_set_frontend_t(struct dvb_frontend *fe, priv->delivery_system = SYS_DVBT; priv->ber_running = 0; /* tune stops BER counter */ - switch (c->bandwidth_hz) { - case 6000000: - i = 0; - bw_param = 2; - break; - case 7000000: - i = 1; - bw_param = 1; - break; - case 8000000: - i = 2; - bw_param = 0; - break; - default: - return -EINVAL; - } - /* program IF frequency */ if (fe->ops.tuner_ops.get_if_frequency) { ret = fe->ops.tuner_ops.get_if_frequency(fe, &if_freq); @@ -116,7 +116,7 @@ int cxd2820r_set_frontend_t(struct dvb_frontend *fe, if (ret) goto error; - ret = cxd2820r_wr_regs(priv, 0x0009f, bw_params1[i], 5); + ret = cxd2820r_wr_regs(priv, 0x0009f, bw_params1[bw_i], 5); if (ret) goto error; @@ -124,7 +124,7 @@ int cxd2820r_set_frontend_t(struct dvb_frontend *fe, if (ret) goto error; - ret = cxd2820r_wr_regs(priv, 0x000d9, bw_params2[i], 2); + ret = cxd2820r_wr_regs(priv, 0x000d9, bw_params2[bw_i], 2); if (ret) goto error; diff --git a/drivers/media/dvb/frontends/cxd2820r_t2.c b/drivers/media/dvb/frontends/cxd2820r_t2.c index 8635b07..e21fc97 100644 --- a/drivers/media/dvb/frontends/cxd2820r_t2.c +++ b/drivers/media/dvb/frontends/cxd2820r_t2.c @@ -26,7 +26,7 @@ int cxd2820r_set_frontend_t2(struct dvb_frontend *fe, { struct cxd2820r_priv *priv = fe->demodulator_priv; struct dtv_frontend_properties *c = &fe->dtv_property_cache; - int ret, i; + int ret, i, bw_i; u32 if_freq, if_ctl; u64 num; u8 buf[3], bw_param; @@ -71,6 +71,27 @@ int cxd2820r_set_frontend_t2(struct dvb_frontend *fe, dbg("%s: RF=%d BW=%d", __func__, c->frequency, c->bandwidth_hz); + switch (c->bandwidth_hz) { + case 5000000: + bw_i = 0; + bw_param = 3; + break; + case 6000000: + bw_i = 1; + bw_param = 2; + break; + case 7000000: + bw_i = 2; + bw_param = 1; + break; + case 8000000: + bw_i = 3; + bw_param = 0; + break; + default: + return -EINVAL; + } + /* update GPIOs */ ret = cxd2820r_gpio(fe); if (ret) @@ -91,27 +112,6 @@ int cxd2820r_set_frontend_t2(struct dvb_frontend *fe, priv->delivery_system = SYS_DVBT2; - switch (c->bandwidth_hz) { - case 5000000: - i = 0; - bw_param = 3; - break; - case 6000000: - i = 1; - bw_param = 2; - break; - case 7000000: - i = 2; - bw_param = 1; - break; - case 8000000: - i = 3; - bw_param = 0; - break; - default: - return -EINVAL; - } - /* program IF frequency */ if (fe->ops.tuner_ops.get_if_frequency) { ret = fe->ops.tuner_ops.get_if_frequency(fe, &if_freq); @@ -133,7 +133,7 @@ int cxd2820r_set_frontend_t2(struct dvb_frontend *fe, if (ret) goto error; - ret = cxd2820r_wr_regs(priv, 0x0209f, bw_params1[i], 5); + ret = cxd2820r_wr_regs(priv, 0x0209f, bw_params1[bw_i], 5); if (ret) goto error; -- cgit v0.10.2 From dc56905fc75cd03aaf05499a93b29755193a159e Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Sun, 13 Nov 2011 15:53:04 -0300 Subject: [media] ce6230: remove experimental from Kconfig I have been working many years without problems. Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/dvb/dvb-usb/Kconfig b/drivers/media/dvb/dvb-usb/Kconfig index 3e316f2..8e7e3a8 100644 --- a/drivers/media/dvb/dvb-usb/Kconfig +++ b/drivers/media/dvb/dvb-usb/Kconfig @@ -341,7 +341,7 @@ config DVB_USB_AF9015 config DVB_USB_CE6230 tristate "Intel CE6230 DVB-T USB2.0 support" - depends on DVB_USB && EXPERIMENTAL + depends on DVB_USB select DVB_ZL10353 select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMISE help -- cgit v0.10.2 From e50f20e1712bc3ebf9cf4c8fc9e6d743ee54626a Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Sun, 13 Nov 2011 15:55:18 -0300 Subject: [media] ce168: remove experimental from Kconfig I have been working many years without problems. Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/dvb/dvb-usb/Kconfig b/drivers/media/dvb/dvb-usb/Kconfig index 8e7e3a8..9f203c6 100644 --- a/drivers/media/dvb/dvb-usb/Kconfig +++ b/drivers/media/dvb/dvb-usb/Kconfig @@ -355,7 +355,7 @@ config DVB_USB_FRIIO config DVB_USB_EC168 tristate "E3C EC168 DVB-T USB2.0 support" - depends on DVB_USB && EXPERIMENTAL + depends on DVB_USB select DVB_EC100 select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMISE help -- cgit v0.10.2 From 37e22142891773fb883bbef435f2ebbb5670c0b0 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Mon, 14 Nov 2011 14:20:49 -0300 Subject: [media] board-dm646x-evm.c: wrong register used in setup_vpif_input_channel_mode The function setup_vpif_input_channel_mode() used the VSCLKDIS register instead of VIDCLKCTL. This meant that when in HD mode videoport channel 0 used a different clock from channel 1. Clearly a copy-and-paste error. Signed-off-by: Hans Verkuil Acked-by: Manjunath Hadli Signed-off-by: Mauro Carvalho Chehab diff --git a/arch/arm/mach-davinci/board-dm646x-evm.c b/arch/arm/mach-davinci/board-dm646x-evm.c index e574d7f..635bf77 100644 --- a/arch/arm/mach-davinci/board-dm646x-evm.c +++ b/arch/arm/mach-davinci/board-dm646x-evm.c @@ -564,7 +564,7 @@ static int setup_vpif_input_channel_mode(int mux_mode) int val; u32 value; - if (!vpif_vsclkdis_reg || !cpld_client) + if (!vpif_vidclkctl_reg || !cpld_client) return -ENXIO; val = i2c_smbus_read_byte(cpld_client); @@ -572,7 +572,7 @@ static int setup_vpif_input_channel_mode(int mux_mode) return val; spin_lock_irqsave(&vpif_reg_lock, flags); - value = __raw_readl(vpif_vsclkdis_reg); + value = __raw_readl(vpif_vidclkctl_reg); if (mux_mode) { val &= VPIF_INPUT_TWO_CHANNEL; value |= VIDCH1CLK; @@ -580,7 +580,7 @@ static int setup_vpif_input_channel_mode(int mux_mode) val |= VPIF_INPUT_ONE_CHANNEL; value &= ~VIDCH1CLK; } - __raw_writel(value, vpif_vsclkdis_reg); + __raw_writel(value, vpif_vidclkctl_reg); spin_unlock_irqrestore(&vpif_reg_lock, flags); err = i2c_smbus_write_byte(cpld_client, val); -- cgit v0.10.2 From 9105b8b200410383d0854bbe237ee385d7d33ba6 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Wed, 16 Nov 2011 01:49:41 -0300 Subject: [media] staging: lirc_serial: Fix init/exit order Currently the module init function registers a platform_device and only then allocates its IRQ and I/O region. This allows allocation to race with the device's suspend() function. Instead, allocate resources in the platform driver's probe() function and free them in the remove() function. The module exit function removes the platform device before the character device that provides access to it. Change it to reverse the order of initialisation. Signed-off-by: Ben Hutchings Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/staging/media/lirc/lirc_serial.c b/drivers/staging/media/lirc/lirc_serial.c index 8a060a8..8637631 100644 --- a/drivers/staging/media/lirc/lirc_serial.c +++ b/drivers/staging/media/lirc/lirc_serial.c @@ -836,7 +836,7 @@ static int hardware_init_port(void) return 0; } -static int init_port(void) +static int __devinit lirc_serial_probe(struct platform_device *dev) { int i, nlow, nhigh, result; @@ -913,6 +913,18 @@ static int init_port(void) return 0; } +static int __devexit lirc_serial_remove(struct platform_device *dev) +{ + free_irq(irq, (void *)&hardware); + + if (iommap != 0) + release_mem_region(iommap, 8 << ioshift); + else + release_region(io, 8); + + return 0; +} + static int set_use_inc(void *data) { unsigned long flags; @@ -1076,16 +1088,6 @@ static struct lirc_driver driver = { static struct platform_device *lirc_serial_dev; -static int __devinit lirc_serial_probe(struct platform_device *dev) -{ - return 0; -} - -static int __devexit lirc_serial_remove(struct platform_device *dev) -{ - return 0; -} - static int lirc_serial_suspend(struct platform_device *dev, pm_message_t state) { @@ -1188,10 +1190,6 @@ static int __init lirc_serial_init_module(void) { int result; - result = lirc_serial_init(); - if (result) - return result; - switch (type) { case LIRC_HOMEBREW: case LIRC_IRDEO: @@ -1211,8 +1209,7 @@ static int __init lirc_serial_init_module(void) break; #endif default: - result = -EINVAL; - goto exit_serial_exit; + return -EINVAL; } if (!softcarrier) { switch (type) { @@ -1228,37 +1225,26 @@ static int __init lirc_serial_init_module(void) } } - result = init_port(); - if (result < 0) - goto exit_serial_exit; + result = lirc_serial_init(); + if (result) + return result; + driver.features = hardware[type].features; driver.dev = &lirc_serial_dev->dev; driver.minor = lirc_register_driver(&driver); if (driver.minor < 0) { printk(KERN_ERR LIRC_DRIVER_NAME ": register_chrdev failed!\n"); - result = -EIO; - goto exit_release; + lirc_serial_exit(); + return -EIO; } return 0; -exit_release: - release_region(io, 8); -exit_serial_exit: - lirc_serial_exit(); - return result; } static void __exit lirc_serial_exit_module(void) { - lirc_serial_exit(); - - free_irq(irq, (void *)&hardware); - - if (iommap != 0) - release_mem_region(iommap, 8 << ioshift); - else - release_region(io, 8); lirc_unregister_driver(driver.minor); + lirc_serial_exit(); dprintk("cleaned up module\n"); } -- cgit v0.10.2 From c8e57e1b766c2321aa76ee5e6878c69bd2313d62 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Wed, 16 Nov 2011 01:52:11 -0300 Subject: [media] staging: lirc_serial: Free resources on failure paths of lirc_serial_probe() Failure to allocate the I/O region leaves the IRQ allocated. A later failure leaves them both allocated. Reported-by: Torsten Crass Signed-off-by: Ben Hutchings Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/staging/media/lirc/lirc_serial.c b/drivers/staging/media/lirc/lirc_serial.c index 8637631..d833772 100644 --- a/drivers/staging/media/lirc/lirc_serial.c +++ b/drivers/staging/media/lirc/lirc_serial.c @@ -875,11 +875,14 @@ static int __devinit lirc_serial_probe(struct platform_device *dev) ": or compile the serial port driver as module and\n"); printk(KERN_WARNING LIRC_DRIVER_NAME ": make sure this module is loaded first\n"); - return -EBUSY; + result = -EBUSY; + goto exit_free_irq; } - if (hardware_init_port() < 0) - return -EINVAL; + if (hardware_init_port() < 0) { + result = -EINVAL; + goto exit_release_region; + } /* Initialize pulse/space widths */ init_timing_params(duty_cycle, freq); @@ -911,6 +914,16 @@ static int __devinit lirc_serial_probe(struct platform_device *dev) dprintk("Interrupt %d, port %04x obtained\n", irq, io); return 0; + +exit_release_region: + if (iommap != 0) + release_mem_region(iommap, 8 << ioshift); + else + release_region(io, 8); +exit_free_irq: + free_irq(irq, (void *)&hardware); + + return result; } static int __devexit lirc_serial_remove(struct platform_device *dev) -- cgit v0.10.2 From 1ff1d88e862948ae5bfe490248c023ff8ac2855d Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Wed, 16 Nov 2011 01:53:25 -0300 Subject: [media] staging: lirc_serial: Fix deadlock on resume failure A resume function cannot remove the device it is resuming! Signed-off-by: Ben Hutchings Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/staging/media/lirc/lirc_serial.c b/drivers/staging/media/lirc/lirc_serial.c index d833772..befe626 100644 --- a/drivers/staging/media/lirc/lirc_serial.c +++ b/drivers/staging/media/lirc/lirc_serial.c @@ -1127,10 +1127,8 @@ static int lirc_serial_resume(struct platform_device *dev) { unsigned long flags; - if (hardware_init_port() < 0) { - lirc_serial_exit(); + if (hardware_init_port() < 0) return -EINVAL; - } spin_lock_irqsave(&hardware[type].lock, flags); /* Enable Interrupt */ -- cgit v0.10.2 From 9b98d60679711753e548be15c6bef5239db6ed64 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Wed, 16 Nov 2011 01:53:35 -0300 Subject: [media] staging: lirc_serial: Fix bogus error codes Device not found? ENODEV, not EINVAL. Write to read-only device? EPERM, not EBADF. Invalid argument? EINVAL, not ENOSYS. Unsupported ioctl? ENOIOCTLCMD, not ENOSYS. Another function returned an error code? Use that, don't replace it. Signed-off-by: Ben Hutchings Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/staging/media/lirc/lirc_serial.c b/drivers/staging/media/lirc/lirc_serial.c index befe626..6f5257e 100644 --- a/drivers/staging/media/lirc/lirc_serial.c +++ b/drivers/staging/media/lirc/lirc_serial.c @@ -773,7 +773,7 @@ static int hardware_init_port(void) /* we fail, there's nothing here */ printk(KERN_ERR LIRC_DRIVER_NAME ": port existence test " "failed, cannot continue\n"); - return -EINVAL; + return -ENODEV; } @@ -879,10 +879,9 @@ static int __devinit lirc_serial_probe(struct platform_device *dev) goto exit_free_irq; } - if (hardware_init_port() < 0) { - result = -EINVAL; + result = hardware_init_port(); + if (result < 0) goto exit_release_region; - } /* Initialize pulse/space widths */ init_timing_params(duty_cycle, freq); @@ -980,7 +979,7 @@ static ssize_t lirc_write(struct file *file, const char *buf, int *wbuf; if (!(hardware[type].features & LIRC_CAN_SEND_PULSE)) - return -EBADF; + return -EPERM; count = n / sizeof(int); if (n % sizeof(int) || count % 2 == 0) @@ -1031,11 +1030,11 @@ static long lirc_ioctl(struct file *filep, unsigned int cmd, unsigned long arg) return result; /* only LIRC_MODE_PULSE supported */ if (value != LIRC_MODE_PULSE) - return -ENOSYS; + return -EINVAL; break; case LIRC_GET_LENGTH: - return -ENOSYS; + return -ENOIOCTLCMD; break; case LIRC_SET_SEND_DUTY_CYCLE: @@ -1126,9 +1125,11 @@ static void lirc_serial_exit(void); static int lirc_serial_resume(struct platform_device *dev) { unsigned long flags; + int result; - if (hardware_init_port() < 0) - return -EINVAL; + result = hardware_init_port(); + if (result < 0) + return result; spin_lock_irqsave(&hardware[type].lock, flags); /* Enable Interrupt */ @@ -1161,7 +1162,7 @@ static int __init lirc_serial_init(void) /* Init read buffer. */ result = lirc_buffer_init(&rbuf, sizeof(int), RBUF_LEN); if (result < 0) - return -ENOMEM; + return result; result = platform_driver_register(&lirc_serial_driver); if (result) { @@ -1247,7 +1248,7 @@ static int __init lirc_serial_init_module(void) printk(KERN_ERR LIRC_DRIVER_NAME ": register_chrdev failed!\n"); lirc_serial_exit(); - return -EIO; + return driver.minor; } return 0; } -- cgit v0.10.2 From affc9a0d59ac49bd304e2137bd5e4ffdd6fdfa52 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Wed, 16 Nov 2011 01:54:04 -0300 Subject: [media] staging: lirc_serial: Do not assume error codes returned by request_irq() lirc_serial_probe() must fail if request_irq() returns an error, even if it isn't EBUSY or EINVAL, Signed-off-by: Ben Hutchings Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/staging/media/lirc/lirc_serial.c b/drivers/staging/media/lirc/lirc_serial.c index 6f5257e..0ca308a 100644 --- a/drivers/staging/media/lirc/lirc_serial.c +++ b/drivers/staging/media/lirc/lirc_serial.c @@ -843,18 +843,15 @@ static int __devinit lirc_serial_probe(struct platform_device *dev) result = request_irq(irq, irq_handler, (share_irq ? IRQF_SHARED : 0), LIRC_DRIVER_NAME, (void *)&hardware); - - switch (result) { - case -EBUSY: - printk(KERN_ERR LIRC_DRIVER_NAME ": IRQ %d busy\n", irq); - return -EBUSY; - case -EINVAL: - printk(KERN_ERR LIRC_DRIVER_NAME - ": Bad irq number or handler\n"); - return -EINVAL; - default: - break; - }; + if (result < 0) { + if (result == -EBUSY) + printk(KERN_ERR LIRC_DRIVER_NAME ": IRQ %d busy\n", + irq); + else if (result == -EINVAL) + printk(KERN_ERR LIRC_DRIVER_NAME + ": Bad irq number or handler\n"); + return result; + } /* Reserve io region. */ /* -- cgit v0.10.2 From bd93b3ad275501f50935a420cb26f598093d91a0 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Wed, 16 Nov 2011 05:14:03 -0300 Subject: [media] media/radio/tef6862: fix checking return value of i2c_master_send i2c_master_send returns negative errno, or else the number of bytes written. Signed-off-by: Axel Lin Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/radio/tef6862.c b/drivers/media/radio/tef6862.c index 0991e19..3408685 100644 --- a/drivers/media/radio/tef6862.c +++ b/drivers/media/radio/tef6862.c @@ -118,9 +118,11 @@ static int tef6862_s_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *f) i2cmsg[2] = pll & 0xff; err = i2c_master_send(client, i2cmsg, sizeof(i2cmsg)); - if (!err) - state->freq = f->frequency; - return err; + if (err != sizeof(i2cmsg)) + return err < 0 ? err : -EIO; + + state->freq = f->frequency; + return 0; } static int tef6862_g_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *f) -- cgit v0.10.2 From 767f1d437db41e888f5da2a79cafd4a11b319cfd Mon Sep 17 00:00:00 2001 From: "Leonid V. Fedorenchik" Date: Sat, 22 Oct 2011 01:43:21 -0300 Subject: [media] cx25821-alsa.c: Line up comments Line up comments to the same column. Signed-off-by: Leonid V. Fedorenchik Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/cx25821/cx25821-alsa.c b/drivers/media/video/cx25821/cx25821-alsa.c index 09e99de..259324a 100644 --- a/drivers/media/video/cx25821/cx25821-alsa.c +++ b/drivers/media/video/cx25821/cx25821-alsa.c @@ -234,15 +234,15 @@ static int _cx25821_stop_audio_dma(struct cx25821_audio_dev *chip) */ static char *cx25821_aud_irqs[32] = { "dn_risci1", "up_risci1", "rds_dn_risc1", /* 0-2 */ - NULL, /* reserved */ + NULL, /* reserved */ "dn_risci2", "up_risci2", "rds_dn_risc2", /* 4-6 */ - NULL, /* reserved */ - "dnf_of", "upf_uf", "rds_dnf_uf", /* 8-10 */ - NULL, /* reserved */ - "dn_sync", "up_sync", "rds_dn_sync", /* 12-14 */ - NULL, /* reserved */ - "opc_err", "par_err", "rip_err", /* 16-18 */ - "pci_abort", "ber_irq", "mchg_irq" /* 19-21 */ + NULL, /* reserved */ + "dnf_of", "upf_uf", "rds_dnf_uf", /* 8-10 */ + NULL, /* reserved */ + "dn_sync", "up_sync", "rds_dn_sync", /* 12-14 */ + NULL, /* reserved */ + "opc_err", "par_err", "rip_err", /* 16-18 */ + "pci_abort", "ber_irq", "mchg_irq" /* 19-21 */ }; /* -- cgit v0.10.2 From 0ef80072014720b79596f9582112034cfe949fd3 Mon Sep 17 00:00:00 2001 From: "Leonid V. Fedorenchik" Date: Sat, 22 Oct 2011 01:43:22 -0300 Subject: [media] cx25821-alsa.c: Add braces to else clause Add curly braces around else clause because corresponding if has them. Signed-off-by: Leonid V. Fedorenchik Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/cx25821/cx25821-alsa.c b/drivers/media/video/cx25821/cx25821-alsa.c index 259324a..92a8694 100644 --- a/drivers/media/video/cx25821/cx25821-alsa.c +++ b/drivers/media/video/cx25821/cx25821-alsa.c @@ -317,8 +317,9 @@ static irqreturn_t cx25821_irq(int irq, void *dev_id) cx25821_aud_irq(chip, audint_status, audint_mask); break; - } else + } else { goto out; + } } handled = 1; -- cgit v0.10.2 From 4d9304c63e654abb8238e40c316e0cd92823ecf4 Mon Sep 17 00:00:00 2001 From: "Leonid V. Fedorenchik" Date: Sat, 22 Oct 2011 01:43:23 -0300 Subject: [media] cx25821-alsa.c: Fix indent Delete unnecessary space before indented statement. Signed-off-by: Leonid V. Fedorenchik Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/cx25821/cx25821-alsa.c b/drivers/media/video/cx25821/cx25821-alsa.c index 92a8694..680a993 100644 --- a/drivers/media/video/cx25821/cx25821-alsa.c +++ b/drivers/media/video/cx25821/cx25821-alsa.c @@ -687,7 +687,7 @@ static int cx25821_audio_initdev(struct cx25821_dev *dev) } err = snd_card_create(index[devno], id[devno], THIS_MODULE, - sizeof(struct cx25821_audio_dev), &card); + sizeof(struct cx25821_audio_dev), &card); if (err < 0) { pr_info("DEBUG ERROR: cannot create snd_card_new in %s\n", __func__); -- cgit v0.10.2 From e5f10621788881e2b53fd7c2717c83aff3813212 Mon Sep 17 00:00:00 2001 From: "Leonid V. Fedorenchik" Date: Sat, 22 Oct 2011 01:43:24 -0300 Subject: [media] cx25821-alsa.c: Change line endings Change obscure line endings to less obscure ones. (improve readability) Signed-off-by: Leonid V. Fedorenchik Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/cx25821/cx25821-alsa.c b/drivers/media/video/cx25821/cx25821-alsa.c index 680a993..6142ae2 100644 --- a/drivers/media/video/cx25821/cx25821-alsa.c +++ b/drivers/media/video/cx25821/cx25821-alsa.c @@ -176,8 +176,7 @@ static int _cx25821_start_audio_dma(struct cx25821_audio_dev *chip) /* Set the input mode to 16-bit */ tmp = cx_read(AUD_A_CFG); - cx_write(AUD_A_CFG, - tmp | FLD_AUD_DST_PK_MODE | FLD_AUD_DST_ENABLE | + cx_write(AUD_A_CFG, tmp | FLD_AUD_DST_PK_MODE | FLD_AUD_DST_ENABLE | FLD_AUD_CLK_ENABLE); /* @@ -188,9 +187,8 @@ static int _cx25821_start_audio_dma(struct cx25821_audio_dev *chip) */ /* Enables corresponding bits at AUD_INT_STAT */ - cx_write(AUD_A_INT_MSK, - FLD_AUD_DST_RISCI1 | FLD_AUD_DST_OF | FLD_AUD_DST_SYNC | - FLD_AUD_DST_OPC_ERR); + cx_write(AUD_A_INT_MSK, FLD_AUD_DST_RISCI1 | FLD_AUD_DST_OF | + FLD_AUD_DST_SYNC | FLD_AUD_DST_OPC_ERR); /* Clean any pending interrupt bits already set */ cx_write(AUD_A_INT_STAT, ~0); @@ -200,8 +198,8 @@ static int _cx25821_start_audio_dma(struct cx25821_audio_dev *chip) /* Turn on audio downstream fifo and risc enable 0x101 */ tmp = cx_read(AUD_INT_DMA_CTL); - cx_set(AUD_INT_DMA_CTL, - tmp | (FLD_AUD_DST_A_RISC_EN | FLD_AUD_DST_A_FIFO_EN)); + cx_set(AUD_INT_DMA_CTL, tmp | + (FLD_AUD_DST_A_RISC_EN | FLD_AUD_DST_A_FIFO_EN)); mdelay(100); return 0; @@ -220,9 +218,8 @@ static int _cx25821_stop_audio_dma(struct cx25821_audio_dev *chip) /* disable irqs */ cx_clear(PCI_INT_MSK, PCI_MSK_AUD_INT); - cx_clear(AUD_A_INT_MSK, - AUD_INT_OPC_ERR | AUD_INT_DN_SYNC | AUD_INT_DN_RISCI2 | - AUD_INT_DN_RISCI1); + cx_clear(AUD_A_INT_MSK, AUD_INT_OPC_ERR | AUD_INT_DN_SYNC | + AUD_INT_DN_RISCI2 | AUD_INT_DN_RISCI1); return 0; } @@ -258,10 +255,8 @@ static void cx25821_aud_irq(struct cx25821_audio_dev *chip, u32 status, cx_write(AUD_A_INT_STAT, status); if (debug > 1 || (status & mask & ~0xff)) - cx25821_print_irqbits(dev->name, "irq aud", - cx25821_aud_irqs, - ARRAY_SIZE(cx25821_aud_irqs), status, - mask); + cx25821_print_irqbits(dev->name, "irq aud", cx25821_aud_irqs, + ARRAY_SIZE(cx25821_aud_irqs), status, mask); /* risc op code error */ if (status & AUD_INT_OPC_ERR) { @@ -270,8 +265,7 @@ static void cx25821_aud_irq(struct cx25821_audio_dev *chip, u32 status, cx_clear(AUD_INT_DMA_CTL, FLD_AUD_DST_A_RISC_EN | FLD_AUD_DST_A_FIFO_EN); cx25821_sram_channel_dump_audio(dev, - &cx25821_sram_channels - [AUDIO_SRAM_CHANNEL]); + &cx25821_sram_channels[AUDIO_SRAM_CHANNEL]); } if (status & AUD_INT_DN_SYNC) { pr_warn("WARNING %s: Downstream sync error!\n", dev->name); @@ -362,9 +356,8 @@ static int dsp_buffer_free(struct cx25821_audio_dev *chip) */ #define DEFAULT_FIFO_SIZE 384 static struct snd_pcm_hardware snd_cx25821_digital_hw = { - .info = SNDRV_PCM_INFO_MMAP | - SNDRV_PCM_INFO_INTERLEAVED | - SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_MMAP_VALID, + .info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | + SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_MMAP_VALID, .formats = SNDRV_PCM_FMTBIT_S16_LE, .rates = SNDRV_PCM_RATE_48000, @@ -397,8 +390,8 @@ static int snd_cx25821_pcm_open(struct snd_pcm_substream *substream) return -ENODEV; } - err = - snd_pcm_hw_constraint_pow2(runtime, 0, SNDRV_PCM_HW_PARAM_PERIODS); + err = snd_pcm_hw_constraint_pow2(runtime, 0, + SNDRV_PCM_HW_PARAM_PERIODS); if (err < 0) goto _error; @@ -469,8 +462,7 @@ static int snd_cx25821_hw_params(struct snd_pcm_substream *substream, dma = &buf->dma; videobuf_dma_init(dma); ret = videobuf_dma_init_kernel(dma, PCI_DMA_FROMDEVICE, - (PAGE_ALIGN(chip->dma_size) >> - PAGE_SHIFT)); + (PAGE_ALIGN(chip->dma_size) >> PAGE_SHIFT)); if (ret < 0) goto error; @@ -478,10 +470,8 @@ static int snd_cx25821_hw_params(struct snd_pcm_substream *substream, if (ret < 0) goto error; - ret = - cx25821_risc_databuffer_audio(chip->pci, &buf->risc, dma->sglist, - chip->period_size, chip->num_periods, - 1); + ret = cx25821_risc_databuffer_audio(chip->pci, &buf->risc, dma->sglist, + chip->period_size, chip->num_periods, 1); if (ret < 0) { pr_info("DEBUG: ERROR after cx25821_risc_databuffer_audio()\n"); goto error; @@ -712,8 +702,8 @@ static int cx25821_audio_initdev(struct cx25821_dev *dev) IRQF_SHARED, chip->dev->name, chip); if (err < 0) { - pr_err("ERROR %s: can't get IRQ %d for ALSA\n", - chip->dev->name, dev->pci->irq); + pr_err("ERROR %s: can't get IRQ %d for ALSA\n", chip->dev->name, + dev->pci->irq); goto error; } @@ -731,8 +721,8 @@ static int cx25821_audio_initdev(struct cx25821_dev *dev) chip->iobase, chip->irq); strcpy(card->mixername, "CX25821"); - pr_info("%s/%i: ALSA support for cx25821 boards\n", - card->driver, devno); + pr_info("%s/%i: ALSA support for cx25821 boards\n", card->driver, + devno); err = snd_card_register(card); if (err < 0) { -- cgit v0.10.2 From 81f4c8dddc804c4ecd0fdcf903d545053ef2857f Mon Sep 17 00:00:00 2001 From: "Leonid V. Fedorenchik" Date: Sat, 22 Oct 2011 01:43:25 -0300 Subject: [media] cx25821-audio-upstream.c: Fix indent Change wrong indent (with spaces and less than 7 columns) of statements to tabs. Signed-off-by: Leonid V. Fedorenchik Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/cx25821/cx25821-audio-upstream.c b/drivers/media/video/cx25821/cx25821-audio-upstream.c index c20d6de..44cb183 100644 --- a/drivers/media/video/cx25821/cx25821-audio-upstream.c +++ b/drivers/media/video/cx25821/cx25821-audio-upstream.c @@ -107,7 +107,7 @@ static __le32 *cx25821_risc_field_upstream_audio(struct cx25821_dev *dev, { unsigned int line; struct sram_channel *sram_ch = - dev->channels[dev->_audio_upstream_channel].sram_channels; + dev->channels[dev->_audio_upstream_channel].sram_channels; int offset = 0; /* scan lines */ @@ -193,7 +193,7 @@ int cx25821_risc_buffer_upstream_audio(struct cx25821_dev *dev, /* Recalculate virtual address based on frame index */ rp = dev->_risc_virt_addr + RISC_SYNC_INSTRUCTION_SIZE / 4 + - (AUDIO_RISC_DMA_BUF_SIZE * (frame + 1) / 4); + (AUDIO_RISC_DMA_BUF_SIZE * (frame + 1) / 4); } return 0; @@ -218,7 +218,7 @@ void cx25821_free_memory_audio(struct cx25821_dev *dev) void cx25821_stop_upstream_audio(struct cx25821_dev *dev) { struct sram_channel *sram_ch = - dev->channels[AUDIO_UPSTREAM_SRAM_CHANNEL_B].sram_channels; + dev->channels[AUDIO_UPSTREAM_SRAM_CHANNEL_B].sram_channels; u32 tmp = 0; if (!dev->_audio_is_running) { @@ -286,14 +286,14 @@ int cx25821_get_audio_data(struct cx25821_dev *dev, } else { if (!(myfile->f_op)) { pr_err("%s(): File has no file operations registered!\n", - __func__); + __func__); filp_close(myfile, NULL); return -EIO; } if (!myfile->f_op->read) { pr_err("%s(): File has no READ operations registered!\n", - __func__); + __func__); filp_close(myfile, NULL); return -EIO; } @@ -312,7 +312,7 @@ int cx25821_get_audio_data(struct cx25821_dev *dev, && dev->_audiodata_buf_virt_addr != NULL) { memcpy((void *)(dev->_audiodata_buf_virt_addr + frame_offset / 4), mybuf, - vfs_read_retval); + vfs_read_retval); } file_offset += vfs_read_retval; @@ -345,7 +345,7 @@ static void cx25821_audioups_handler(struct work_struct *work) if (!dev) { pr_err("ERROR %s(): since container_of(work_struct) FAILED!\n", - __func__); + __func__); return; } @@ -370,19 +370,19 @@ int cx25821_openfile_audio(struct cx25821_dev *dev, if (IS_ERR(myfile)) { const int open_errno = -PTR_ERR(myfile); pr_err("%s(): ERROR opening file(%s) with errno = %d!\n", - __func__, dev->_audiofilename, open_errno); + __func__, dev->_audiofilename, open_errno); return PTR_ERR(myfile); } else { if (!(myfile->f_op)) { pr_err("%s(): File has no file operations registered!\n", - __func__); + __func__); filp_close(myfile, NULL); return -EIO; } if (!myfile->f_op->read) { pr_err("%s(): File has no READ operations registered!\n", - __func__); + __func__); filp_close(myfile, NULL); return -EIO; } @@ -454,7 +454,7 @@ static int cx25821_audio_upstream_buffer_prepare(struct cx25821_dev *dev, if (!dev->_risc_virt_addr) { printk(KERN_DEBUG - pr_fmt("ERROR: pci_alloc_consistent() FAILED to allocate memory for RISC program! Returning\n")); + pr_fmt("ERROR: pci_alloc_consistent() FAILED to allocate memory for RISC program! Returning\n")); return -ENOMEM; } /* Clear out memory at address */ @@ -469,7 +469,7 @@ static int cx25821_audio_upstream_buffer_prepare(struct cx25821_dev *dev, if (!dev->_audiodata_buf_virt_addr) { printk(KERN_DEBUG - pr_fmt("ERROR: pci_alloc_consistent() FAILED to allocate memory for data buffer! Returning\n")); + pr_fmt("ERROR: pci_alloc_consistent() FAILED to allocate memory for data buffer! Returning\n")); return -ENOMEM; } /* Clear out memory at address */ @@ -485,7 +485,7 @@ static int cx25821_audio_upstream_buffer_prepare(struct cx25821_dev *dev, dev->_audio_lines_count); if (ret < 0) { printk(KERN_DEBUG - pr_fmt("ERROR creating audio upstream RISC programs!\n")); + pr_fmt("ERROR creating audio upstream RISC programs!\n")); goto error; } @@ -533,9 +533,9 @@ int cx25821_audio_upstream_irq(struct cx25821_dev *dev, int chan_num, if (dev->_risc_virt_start_addr != NULL) { risc_phys_jump_addr = - dev->_risc_phys_start_addr + - RISC_SYNC_INSTRUCTION_SIZE + - AUDIO_RISC_DMA_BUF_SIZE; + dev->_risc_phys_start_addr + + RISC_SYNC_INSTRUCTION_SIZE + + AUDIO_RISC_DMA_BUF_SIZE; rp = cx25821_risc_field_upstream_audio(dev, dev->_risc_virt_start_addr + 1, @@ -632,7 +632,7 @@ static void cx25821_wait_fifo_enable(struct cx25821_dev *dev, /* 10 millisecond timeout */ if (count++ > 1000) { pr_err("ERROR: %s() fifo is NOT turned on. Timeout!\n", - __func__); + __func__); return; } @@ -726,7 +726,7 @@ int cx25821_audio_upstream_init(struct cx25821_dev *dev, int channel_select) if (!dev->_irq_audio_queues) { printk(KERN_DEBUG - pr_fmt("ERROR: create_singlethread_workqueue() for Audio FAILED!\n")); + pr_fmt("ERROR: create_singlethread_workqueue() for Audio FAILED!\n")); return -ENOMEM; } @@ -764,8 +764,8 @@ int cx25821_audio_upstream_init(struct cx25821_dev *dev, int channel_select) _line_size, 0); dev->audio_upstream_riscbuf_size = - AUDIO_RISC_DMA_BUF_SIZE * NUM_AUDIO_PROGS + - RISC_SYNC_INSTRUCTION_SIZE; + AUDIO_RISC_DMA_BUF_SIZE * NUM_AUDIO_PROGS + + RISC_SYNC_INSTRUCTION_SIZE; dev->audio_upstream_databuf_size = AUDIO_DATA_BUF_SZ * NUM_AUDIO_PROGS; /* Allocating buffers and prepare RISC program */ @@ -773,7 +773,7 @@ int cx25821_audio_upstream_init(struct cx25821_dev *dev, int channel_select) _line_size); if (retval < 0) { pr_err("%s: Failed to set up Audio upstream buffers!\n", - dev->name); + dev->name); goto error; } /* Start RISC engine */ -- cgit v0.10.2 From 64dcb194969d8d4447911e69f8b633ff2b87be40 Mon Sep 17 00:00:00 2001 From: "Leonid V. Fedorenchik" Date: Sat, 22 Oct 2011 01:43:26 -0300 Subject: [media] cx25821-audio-upstream.c: Move operators Move operator of complex expression to the end of the lines to preserve consistency. Signed-off-by: Leonid V. Fedorenchik Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/cx25821/cx25821-audio-upstream.c b/drivers/media/video/cx25821/cx25821-audio-upstream.c index 44cb183..a221b95 100644 --- a/drivers/media/video/cx25821/cx25821-audio-upstream.c +++ b/drivers/media/video/cx25821/cx25821-audio-upstream.c @@ -398,9 +398,9 @@ int cx25821_openfile_audio(struct cx25821_dev *dev, vfs_read_retval = vfs_read(myfile, mybuf, line_size, &pos); - if (vfs_read_retval > 0 - && vfs_read_retval == line_size - && dev->_audiodata_buf_virt_addr != NULL) { + if (vfs_read_retval > 0 && + vfs_read_retval == line_size && + dev->_audiodata_buf_virt_addr != NULL) { memcpy((void *)(dev-> _audiodata_buf_virt_addr + offset / 4), mybuf, -- cgit v0.10.2 From 72a52fc3254512c5bcc70a03f33571cd50ee33a1 Mon Sep 17 00:00:00 2001 From: "Leonid V. Fedorenchik" Date: Sat, 22 Oct 2011 01:43:27 -0300 Subject: [media] cx25821-audio-upstream.c: Change line endings Change obscure line endings to less obscure ones. (improve readability) Signed-off-by: Leonid V. Fedorenchik Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/cx25821/cx25821-audio-upstream.c b/drivers/media/video/cx25821/cx25821-audio-upstream.c index a221b95..4dc2a24 100644 --- a/drivers/media/video/cx25821/cx25821-audio-upstream.c +++ b/drivers/media/video/cx25821/cx25821-audio-upstream.c @@ -175,10 +175,8 @@ int cx25821_risc_buffer_upstream_audio(struct cx25821_dev *dev, } rp = cx25821_risc_field_upstream_audio(dev, rp, - dev-> - _audiodata_buf_phys_addr - + databuf_offset, bpl, - fifo_enable); + dev->_audiodata_buf_phys_addr + databuf_offset, + bpl, fifo_enable); if (USE_RISC_NOOP_AUDIO) { for (i = 0; i < NUM_NO_OPS; i++) @@ -305,8 +303,8 @@ int cx25821_get_audio_data(struct cx25821_dev *dev, for (i = 0; i < dev->_audio_lines_count; i++) { pos = file_offset; - vfs_read_retval = - vfs_read(myfile, mybuf, line_size, &pos); + vfs_read_retval = vfs_read(myfile, mybuf, line_size, + &pos); if (vfs_read_retval > 0 && vfs_read_retval == line_size && dev->_audiodata_buf_virt_addr != NULL) { @@ -328,8 +326,8 @@ int cx25821_get_audio_data(struct cx25821_dev *dev, if (i > 0) dev->_audioframe_count++; - dev->_audiofile_status = - (vfs_read_retval == line_size) ? IN_PROGRESS : END_OF_FILE; + dev->_audiofile_status = (vfs_read_retval == line_size) ? + IN_PROGRESS : END_OF_FILE; set_fs(old_fs); filp_close(myfile, NULL); @@ -340,8 +338,8 @@ int cx25821_get_audio_data(struct cx25821_dev *dev, static void cx25821_audioups_handler(struct work_struct *work) { - struct cx25821_dev *dev = - container_of(work, struct cx25821_dev, _audio_work_entry); + struct cx25821_dev *dev = container_of(work, struct cx25821_dev, + _audio_work_entry); if (!dev) { pr_err("ERROR %s(): since container_of(work_struct) FAILED!\n", @@ -395,8 +393,8 @@ int cx25821_openfile_audio(struct cx25821_dev *dev, for (i = 0; i < dev->_audio_lines_count; i++) { pos = offset; - vfs_read_retval = - vfs_read(myfile, mybuf, line_size, &pos); + vfs_read_retval = vfs_read(myfile, mybuf, + line_size, &pos); if (vfs_read_retval > 0 && vfs_read_retval == line_size && @@ -423,8 +421,8 @@ int cx25821_openfile_audio(struct cx25821_dev *dev, break; } - dev->_audiofile_status = - (vfs_read_retval == line_size) ? IN_PROGRESS : END_OF_FILE; + dev->_audiofile_status = (vfs_read_retval == line_size) ? + IN_PROGRESS : END_OF_FILE; set_fs(old_fs); myfile->f_pos = 0; @@ -444,9 +442,8 @@ static int cx25821_audio_upstream_buffer_prepare(struct cx25821_dev *dev, cx25821_free_memory_audio(dev); - dev->_risc_virt_addr = - pci_alloc_consistent(dev->pci, dev->audio_upstream_riscbuf_size, - &dma_addr); + dev->_risc_virt_addr = pci_alloc_consistent(dev->pci, + dev->audio_upstream_riscbuf_size, &dma_addr); dev->_risc_virt_start_addr = dev->_risc_virt_addr; dev->_risc_phys_start_addr = dma_addr; dev->_risc_phys_addr = dma_addr; @@ -461,9 +458,8 @@ static int cx25821_audio_upstream_buffer_prepare(struct cx25821_dev *dev, memset(dev->_risc_virt_addr, 0, dev->_audiorisc_size); /* For Audio Data buffer allocation */ - dev->_audiodata_buf_virt_addr = - pci_alloc_consistent(dev->pci, dev->audio_upstream_databuf_size, - &data_dma_addr); + dev->_audiodata_buf_virt_addr = pci_alloc_consistent(dev->pci, + dev->audio_upstream_databuf_size, &data_dma_addr); dev->_audiodata_buf_phys_addr = data_dma_addr; dev->_audiodata_buf_size = dev->audio_upstream_databuf_size; @@ -480,9 +476,8 @@ static int cx25821_audio_upstream_buffer_prepare(struct cx25821_dev *dev, return ret; /* Creating RISC programs */ - ret = - cx25821_risc_buffer_upstream_audio(dev, dev->pci, bpl, - dev->_audio_lines_count); + ret = cx25821_risc_buffer_upstream_audio(dev, dev->pci, bpl, + dev->_audio_lines_count); if (ret < 0) { printk(KERN_DEBUG pr_fmt("ERROR creating audio upstream RISC programs!\n")); @@ -661,9 +656,9 @@ int cx25821_start_audio_dma_upstream(struct cx25821_dev *dev, /* Set the input mode to 16-bit */ tmp = cx_read(sram_ch->aud_cfg); - tmp |= - FLD_AUD_SRC_ENABLE | FLD_AUD_DST_PK_MODE | FLD_AUD_CLK_ENABLE | - FLD_AUD_MASTER_MODE | FLD_AUD_CLK_SELECT_PLL_D | FLD_AUD_SONY_MODE; + tmp |= FLD_AUD_SRC_ENABLE | FLD_AUD_DST_PK_MODE | FLD_AUD_CLK_ENABLE | + FLD_AUD_MASTER_MODE | FLD_AUD_CLK_SELECT_PLL_D | + FLD_AUD_SONY_MODE; cx_write(sram_ch->aud_cfg, tmp); /* Read and write back the interrupt status register to clear it */ @@ -678,12 +673,11 @@ int cx25821_start_audio_dma_upstream(struct cx25821_dev *dev, tmp = cx_read(sram_ch->int_msk); cx_write(sram_ch->int_msk, tmp |= _intr_msk); - err = - request_irq(dev->pci->irq, cx25821_upstream_irq_audio, + err = request_irq(dev->pci->irq, cx25821_upstream_irq_audio, IRQF_SHARED, dev->name, dev); if (err < 0) { - pr_err("%s: can't get upstream IRQ %d\n", - dev->name, dev->pci->irq); + pr_err("%s: can't get upstream IRQ %d\n", dev->name, + dev->pci->irq); goto fail_irq; } -- cgit v0.10.2 From 8e249581611bfc98c1ec18b6e124b613b6b6db1b Mon Sep 17 00:00:00 2001 From: "Leonid V. Fedorenchik" Date: Sat, 22 Oct 2011 01:43:28 -0300 Subject: [media] cx25821-audio.h: Line up defines Line up defines to the same column. Signed-off-by: Leonid V. Fedorenchik Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/cx25821/cx25821-audio.h b/drivers/media/video/cx25821/cx25821-audio.h index 8eb55b7..57bdced 100644 --- a/drivers/media/video/cx25821/cx25821-audio.h +++ b/drivers/media/video/cx25821/cx25821-audio.h @@ -23,12 +23,12 @@ #ifndef __CX25821_AUDIO_H__ #define __CX25821_AUDIO_H__ -#define USE_RISC_NOOP 1 -#define LINES_PER_BUFFER 15 -#define AUDIO_LINE_SIZE 128 +#define USE_RISC_NOOP 1 +#define LINES_PER_BUFFER 15 +#define AUDIO_LINE_SIZE 128 /* Number of buffer programs to use at once. */ -#define NUMBER_OF_PROGRAMS 8 +#define NUMBER_OF_PROGRAMS 8 /* * Max size of the RISC program for a buffer. - worst case is 2 writes per line -- cgit v0.10.2 From 6f1f0e85da9be5a2ffddf42751400f619b503d62 Mon Sep 17 00:00:00 2001 From: "Leonid V. Fedorenchik" Date: Sat, 22 Oct 2011 01:43:29 -0300 Subject: [media] cx25821-audio.h: Fix multiline defines Change column of line continuation character ('\') and fix indent of multiline defines. Also line up remaining constant defines. Signed-off-by: Leonid V. Fedorenchik Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/cx25821/cx25821-audio.h b/drivers/media/video/cx25821/cx25821-audio.h index 57bdced..1fc2d24 100644 --- a/drivers/media/video/cx25821/cx25821-audio.h +++ b/drivers/media/video/cx25821/cx25821-audio.h @@ -35,27 +35,28 @@ * Space is also added for the 4 no-op instructions added on the end. */ #ifndef USE_RISC_NOOP -#define MAX_BUFFER_PROGRAM_SIZE \ - (2 * LINES_PER_BUFFER * RISC_WRITE_INSTRUCTION_SIZE + \ - RISC_WRITECR_INSTRUCTION_SIZE * 4) +#define MAX_BUFFER_PROGRAM_SIZE \ + (2 * LINES_PER_BUFFER * RISC_WRITE_INSTRUCTION_SIZE + \ + RISC_WRITECR_INSTRUCTION_SIZE * 4) #endif /* MAE 12 July 2005 Try to use NOOP RISC instruction instead */ #ifdef USE_RISC_NOOP -#define MAX_BUFFER_PROGRAM_SIZE \ - (2 * LINES_PER_BUFFER * RISC_WRITE_INSTRUCTION_SIZE + \ - RISC_NOOP_INSTRUCTION_SIZE * 4) +#define MAX_BUFFER_PROGRAM_SIZE \ + (2 * LINES_PER_BUFFER * RISC_WRITE_INSTRUCTION_SIZE + \ + RISC_NOOP_INSTRUCTION_SIZE * 4) #endif /* Sizes of various instructions in bytes. Used when adding instructions. */ -#define RISC_WRITE_INSTRUCTION_SIZE 12 -#define RISC_JUMP_INSTRUCTION_SIZE 12 -#define RISC_SKIP_INSTRUCTION_SIZE 4 -#define RISC_SYNC_INSTRUCTION_SIZE 4 -#define RISC_WRITECR_INSTRUCTION_SIZE 16 -#define RISC_NOOP_INSTRUCTION_SIZE 4 - -#define MAX_AUDIO_DMA_BUFFER_SIZE \ -(MAX_BUFFER_PROGRAM_SIZE * NUMBER_OF_PROGRAMS + RISC_SYNC_INSTRUCTION_SIZE) +#define RISC_WRITE_INSTRUCTION_SIZE 12 +#define RISC_JUMP_INSTRUCTION_SIZE 12 +#define RISC_SKIP_INSTRUCTION_SIZE 4 +#define RISC_SYNC_INSTRUCTION_SIZE 4 +#define RISC_WRITECR_INSTRUCTION_SIZE 16 +#define RISC_NOOP_INSTRUCTION_SIZE 4 + +#define MAX_AUDIO_DMA_BUFFER_SIZE \ + (MAX_BUFFER_PROGRAM_SIZE * NUMBER_OF_PROGRAMS + \ + RISC_SYNC_INSTRUCTION_SIZE) #endif -- cgit v0.10.2 From 744992c01162d8a51e667454bd7a886b6e28008e Mon Sep 17 00:00:00 2001 From: "Leonid V. Fedorenchik" Date: Sat, 22 Oct 2011 01:43:30 -0300 Subject: [media] cx25821-cards.c: Fix indent Fix indent of statement to use tab instead of spaces. Signed-off-by: Leonid V. Fedorenchik Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/cx25821/cx25821-cards.c b/drivers/media/video/cx25821/cx25821-cards.c index 6ace603..99988c9 100644 --- a/drivers/media/video/cx25821/cx25821-cards.c +++ b/drivers/media/video/cx25821/cx25821-cards.c @@ -67,6 +67,6 @@ void cx25821_card_setup(struct cx25821_dev *dev) if (dev->i2c_bus[0].i2c_rc == 0) { dev->i2c_bus[0].i2c_client.addr = 0xa0 >> 1; tveeprom_read(&dev->i2c_bus[0].i2c_client, eeprom, - sizeof(eeprom)); + sizeof(eeprom)); } } -- cgit v0.10.2 From 43365d5d135eef910fcc1f211d9668e561517b0c Mon Sep 17 00:00:00 2001 From: "Leonid V. Fedorenchik" Date: Sat, 22 Oct 2011 01:43:31 -0300 Subject: [media] cx25821-core.c: Delete empty line Delete redundant empty line. Signed-off-by: Leonid V. Fedorenchik Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/cx25821/cx25821-core.c b/drivers/media/video/cx25821/cx25821-core.c index a7fa38f..f3f6c76 100644 --- a/drivers/media/video/cx25821/cx25821-core.c +++ b/drivers/media/video/cx25821/cx25821-core.c @@ -1512,6 +1512,5 @@ static void __exit cx25821_fini(void) pci_unregister_driver(&cx25821_pci_driver); } - module_init(cx25821_init); module_exit(cx25821_fini); -- cgit v0.10.2 From c14ea5e59f80082fc58bfabe300ae5a6560f7958 Mon Sep 17 00:00:00 2001 From: "Leonid V. Fedorenchik" Date: Sat, 22 Oct 2011 01:43:32 -0300 Subject: [media] cx25821-core.c: Fix indent Change indent of statements that indented with spaces to indent with tabs. Signed-off-by: Leonid V. Fedorenchik Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/cx25821/cx25821-core.c b/drivers/media/video/cx25821/cx25821-core.c index f3f6c76..35f543d 100644 --- a/drivers/media/video/cx25821/cx25821-core.c +++ b/drivers/media/video/cx25821/cx25821-core.c @@ -869,7 +869,7 @@ static int cx25821_get_resources(struct cx25821_dev *dev) return 0; pr_err("%s: can't get MMIO memory @ 0x%llx\n", - dev->name, (unsigned long long)pci_resource_start(dev->pci, 0)); + dev->name, (unsigned long long)pci_resource_start(dev->pci, 0)); return -EBUSY; } @@ -994,7 +994,7 @@ static int cx25821_dev_setup(struct cx25821_dev *dev) * cx25821_i2c_register(&dev->i2c_bus[2]); */ CX25821_INFO("i2c register! bus->i2c_rc = %d\n", - dev->i2c_bus[0].i2c_rc); + dev->i2c_bus[0].i2c_rc); cx25821_card_setup(dev); @@ -1224,7 +1224,7 @@ static __le32 *cx25821_risc_field_audio(__le32 * rp, struct scatterlist *sglist, /* scanline needs to be split */ todo = bpl; *(rp++) = cpu_to_le32(RISC_WRITE | sol | - (sg_dma_len(sg) - offset)); + (sg_dma_len(sg) - offset)); *(rp++) = cpu_to_le32(sg_dma_address(sg) + offset); *(rp++) = cpu_to_le32(0); /* bits 63-32 */ todo -= (sg_dma_len(sg) - offset); @@ -1232,7 +1232,7 @@ static __le32 *cx25821_risc_field_audio(__le32 * rp, struct scatterlist *sglist, sg++; while (todo > sg_dma_len(sg)) { *(rp++) = cpu_to_le32(RISC_WRITE | - sg_dma_len(sg)); + sg_dma_len(sg)); *(rp++) = cpu_to_le32(sg_dma_address(sg)); *(rp++) = cpu_to_le32(0); /* bits 63-32 */ todo -= sg_dma_len(sg); -- cgit v0.10.2 From 3f0bfe5bbd63279fbb278659e9709b90040bfb20 Mon Sep 17 00:00:00 2001 From: "Leonid V. Fedorenchik" Date: Sat, 22 Oct 2011 01:43:33 -0300 Subject: [media] cx25821-core.c: Change line endings Change obscure line endings to less obscure ones. (improve readability) Signed-off-by: Leonid V. Fedorenchik Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/cx25821/cx25821-core.c b/drivers/media/video/cx25821/cx25821-core.c index 35f543d..f617474 100644 --- a/drivers/media/video/cx25821/cx25821-core.c +++ b/drivers/media/video/cx25821/cx25821-core.c @@ -804,8 +804,8 @@ void cx25821_set_pixel_format(struct cx25821_dev *dev, int channel_select, u32 format) { if (channel_select <= 7 && channel_select >= 0) { - cx_write(dev->channels[channel_select]. - sram_channels->pix_frmt, format); + cx_write(dev->channels[channel_select].sram_channels->pix_frmt, + format); dev->channels[channel_select].pixel_formats = format; } } @@ -855,17 +855,15 @@ static void cx25821_initialize(struct cx25821_dev *dev) } cx25821_sram_channel_setup_audio(dev, - dev->channels[SRAM_CH08].sram_channels, - 128, 0); + dev->channels[SRAM_CH08].sram_channels, 128, 0); cx25821_gpio_init(dev); } static int cx25821_get_resources(struct cx25821_dev *dev) { - if (request_mem_region - (pci_resource_start(dev->pci, 0), pci_resource_len(dev->pci, 0), - dev->name)) + if (request_mem_region(pci_resource_start(dev->pci, 0), + pci_resource_len(dev->pci, 0), dev->name)) return 0; pr_err("%s: can't get MMIO memory @ 0x%llx\n", @@ -972,8 +970,7 @@ static int cx25821_dev_setup(struct cx25821_dev *dev) dev->lmmio = ioremap(dev->base_io_addr, pci_resource_len(dev->pci, 0)); if (!dev->lmmio) { - CX25821_ERR - ("ioremap failed, maybe increasing __VMALLOC_RESERVE in page.h\n"); + CX25821_ERR("ioremap failed, maybe increasing __VMALLOC_RESERVE in page.h\n"); cx25821_iounmap(dev); return -ENOMEM; } @@ -1004,9 +1001,8 @@ static int cx25821_dev_setup(struct cx25821_dev *dev) cx25821_video_register(dev); /* register IOCTL device */ - dev->ioctl_dev = - cx25821_vdev_init(dev, dev->pci, &cx25821_videoioctl_template, - "video"); + dev->ioctl_dev = cx25821_vdev_init(dev, dev->pci, + &cx25821_videoioctl_template, "video"); if (video_register_device (dev->ioctl_dev, VFL_TYPE_GRABBER, VIDEO_IOCTL_CH) < 0) { @@ -1103,16 +1099,15 @@ static __le32 *cx25821_risc_field(__le32 * rp, struct scatterlist *sglist, } if (bpl <= sg_dma_len(sg) - offset) { /* fits into current chunk */ - *(rp++) = - cpu_to_le32(RISC_WRITE | RISC_SOL | RISC_EOL | bpl); + *(rp++) = cpu_to_le32(RISC_WRITE | RISC_SOL | RISC_EOL | + bpl); *(rp++) = cpu_to_le32(sg_dma_address(sg) + offset); *(rp++) = cpu_to_le32(0); /* bits 63-32 */ offset += bpl; } else { /* scanline needs to be split */ todo = bpl; - *(rp++) = - cpu_to_le32(RISC_WRITE | RISC_SOL | + *(rp++) = cpu_to_le32(RISC_WRITE | RISC_SOL | (sg_dma_len(sg) - offset)); *(rp++) = cpu_to_le32(sg_dma_address(sg) + offset); *(rp++) = cpu_to_le32(0); /* bits 63-32 */ @@ -1120,8 +1115,8 @@ static __le32 *cx25821_risc_field(__le32 * rp, struct scatterlist *sglist, offset = 0; sg++; while (todo > sg_dma_len(sg)) { - *(rp++) = - cpu_to_le32(RISC_WRITE | sg_dma_len(sg)); + *(rp++) = cpu_to_le32(RISC_WRITE | + sg_dma_len(sg)); *(rp++) = cpu_to_le32(sg_dma_address(sg)); *(rp++) = cpu_to_le32(0); /* bits 63-32 */ todo -= sg_dma_len(sg); @@ -1160,8 +1155,8 @@ int cx25821_risc_buffer(struct pci_dev *pci, struct btcx_riscmem *risc, can cause next bpl to start close to a page border. First DMA region may be smaller than PAGE_SIZE */ /* write and jump need and extra dword */ - instructions = - fields * (1 + ((bpl + padding) * lines) / PAGE_SIZE + lines); + instructions = fields * (1 + ((bpl + padding) * lines) / PAGE_SIZE + + lines); instructions += 2; rc = btcx_riscmem_alloc(pci, risc, instructions * 12); @@ -1215,8 +1210,8 @@ static __le32 *cx25821_risc_field_audio(__le32 * rp, struct scatterlist *sglist, if (bpl <= sg_dma_len(sg) - offset) { /* fits into current chunk */ - *(rp++) = - cpu_to_le32(RISC_WRITE | sol | RISC_EOL | bpl); + *(rp++) = cpu_to_le32(RISC_WRITE | sol | RISC_EOL | + bpl); *(rp++) = cpu_to_le32(sg_dma_address(sg) + offset); *(rp++) = cpu_to_le32(0); /* bits 63-32 */ offset += bpl; @@ -1339,8 +1334,8 @@ static irqreturn_t cx25821_irq(int irq, void *dev_id) sram_channels->int_stat); if (vid_status) - handled += - cx25821_video_irq(dev, i, vid_status); + handled += cx25821_video_irq(dev, i, + vid_status); cx_write(PCI_INT_STAT, mask[i]); } @@ -1427,9 +1422,8 @@ static int __devinit cx25821_initdev(struct pci_dev *pci_dev, goto fail_irq; } - err = - request_irq(pci_dev->irq, cx25821_irq, IRQF_SHARED, - dev->name, dev); + err = request_irq(pci_dev->irq, cx25821_irq, + IRQF_SHARED, dev->name, dev); if (err < 0) { pr_err("%s: can't get IRQ %d\n", dev->name, pci_dev->irq); -- cgit v0.10.2 From 654d075d5db3220af1385980acba8f9417c0f36a Mon Sep 17 00:00:00 2001 From: "Leonid V. Fedorenchik" Date: Sat, 22 Oct 2011 01:43:34 -0300 Subject: [media] cx25821-i2c.c: Change line endings Change obscure line endings to less obscure ones. (improve readability) Signed-off-by: Leonid V. Fedorenchik Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/cx25821/cx25821-i2c.c b/drivers/media/video/cx25821/cx25821-i2c.c index 77fa8eb..12d7300 100644 --- a/drivers/media/video/cx25821/cx25821-i2c.c +++ b/drivers/media/video/cx25821/cx25821-i2c.c @@ -252,8 +252,8 @@ static int i2c_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs, int num) } else if (i + 1 < num && (msgs[i + 1].flags & I2C_M_RD) && msgs[i].addr == msgs[i + 1].addr) { /* write then read from same address */ - retval = - i2c_sendbytes(i2c_adap, &msgs[i], msgs[i + 1].len); + retval = i2c_sendbytes(i2c_adap, &msgs[i], + msgs[i + 1].len); if (retval < 0) goto err; @@ -276,10 +276,8 @@ err: static u32 cx25821_functionality(struct i2c_adapter *adap) { - return I2C_FUNC_SMBUS_EMUL | - I2C_FUNC_I2C | - I2C_FUNC_SMBUS_WORD_DATA | - I2C_FUNC_SMBUS_READ_WORD_DATA | I2C_FUNC_SMBUS_WRITE_WORD_DATA; + return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_I2C | I2C_FUNC_SMBUS_WORD_DATA | + I2C_FUNC_SMBUS_READ_WORD_DATA | I2C_FUNC_SMBUS_WRITE_WORD_DATA; } static struct i2c_algorithm cx25821_i2c_algo_template = { -- cgit v0.10.2 From bc8b5dcaf5939045d89efa737b1ef583171e2436 Mon Sep 17 00:00:00 2001 From: "Leonid V. Fedorenchik" Date: Sat, 22 Oct 2011 01:43:35 -0300 Subject: [media] cx25821-medusa-defines.h: Fix typo Fix typo in comment in word 'decoder'. Signed-off-by: Leonid V. Fedorenchik Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/cx25821/cx25821-medusa-defines.h b/drivers/media/video/cx25821/cx25821-medusa-defines.h index 60d197f..07a6141 100644 --- a/drivers/media/video/cx25821/cx25821-medusa-defines.h +++ b/drivers/media/video/cx25821/cx25821-medusa-defines.h @@ -23,7 +23,7 @@ #ifndef _MEDUSA_DEF_H_ #define _MEDUSA_DEF_H_ -/* Video deocder that we supported */ +/* Video decoder that we supported */ #define VDEC_A 0 #define VDEC_B 1 #define VDEC_C 2 -- cgit v0.10.2 From 7618aa0e46564aeaa7a48588fac4bc21a78f666b Mon Sep 17 00:00:00 2001 From: "Leonid V. Fedorenchik" Date: Sat, 22 Oct 2011 01:43:36 -0300 Subject: [media] cx25821-medusa-defines.h: Line up defines Line up constant defines to the same column. Signed-off-by: Leonid V. Fedorenchik Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/cx25821/cx25821-medusa-defines.h b/drivers/media/video/cx25821/cx25821-medusa-defines.h index 07a6141..7a9e647 100644 --- a/drivers/media/video/cx25821/cx25821-medusa-defines.h +++ b/drivers/media/video/cx25821/cx25821-medusa-defines.h @@ -34,9 +34,9 @@ #define VDEC_H 7 /* end of display sequence */ -#define END_OF_SEQ 0xF; +#define END_OF_SEQ 0xF; /* registry string size */ -#define MAX_REGISTRY_SZ 40; +#define MAX_REGISTRY_SZ 40; #endif -- cgit v0.10.2 From f70a6566d3fb0dd7ebf7dd4db127550f3c52d775 Mon Sep 17 00:00:00 2001 From: "Leonid V. Fedorenchik" Date: Sat, 22 Oct 2011 01:43:37 -0300 Subject: [media] cx25821-medusa-reg.h: Line up defines Line up constant defines to the same column. (also delete unnecessary spaces in comments) Signed-off-by: Leonid V. Fedorenchik Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/cx25821/cx25821-medusa-reg.h b/drivers/media/video/cx25821/cx25821-medusa-reg.h index 1c1c228..c98ac94 100644 --- a/drivers/media/video/cx25821/cx25821-medusa-reg.h +++ b/drivers/media/video/cx25821/cx25821-medusa-reg.h @@ -28,22 +28,22 @@ #define HOST_REGISTER2 0x0001 /* Chip Configuration Registers */ -#define CHIP_CTRL 0x0100 -#define AFE_AB_CTRL 0x0104 -#define AFE_CD_CTRL 0x0108 -#define AFE_EF_CTRL 0x010C -#define AFE_GH_CTRL 0x0110 +#define CHIP_CTRL 0x0100 +#define AFE_AB_CTRL 0x0104 +#define AFE_CD_CTRL 0x0108 +#define AFE_EF_CTRL 0x010C +#define AFE_GH_CTRL 0x0110 #define DENC_AB_CTRL 0x0114 -#define BYP_AB_CTRL 0x0118 -#define MON_A_CTRL 0x011C -#define DISP_SEQ_A 0x0120 -#define DISP_SEQ_B 0x0124 -#define DISP_AB_CNT 0x0128 -#define DISP_CD_CNT 0x012C -#define DISP_EF_CNT 0x0130 -#define DISP_GH_CNT 0x0134 -#define DISP_IJ_CNT 0x0138 -#define PIN_OE_CTRL 0x013C +#define BYP_AB_CTRL 0x0118 +#define MON_A_CTRL 0x011C +#define DISP_SEQ_A 0x0120 +#define DISP_SEQ_B 0x0124 +#define DISP_AB_CNT 0x0128 +#define DISP_CD_CNT 0x012C +#define DISP_EF_CNT 0x0130 +#define DISP_GH_CNT 0x0134 +#define DISP_IJ_CNT 0x0138 +#define PIN_OE_CTRL 0x013C #define PIN_SPD_CTRL 0x0140 #define PIN_SPD_CTRL2 0x0144 #define IRQ_STAT_CTRL 0x0148 @@ -51,8 +51,8 @@ #define POWER_CTRL_CD 0x0150 #define POWER_CTRL_EF 0x0154 #define POWER_CTRL_GH 0x0158 -#define TUNE_CTRL 0x015C -#define BIAS_CTRL 0x0160 +#define TUNE_CTRL 0x015C +#define BIAS_CTRL 0x0160 #define AFE_AB_DIAG_CTRL 0x0164 #define AFE_CD_DIAG_CTRL 0x0168 #define AFE_EF_DIAG_CTRL 0x016C @@ -61,17 +61,17 @@ #define PLL_CD_DIAG_CTRL 0x0178 #define PLL_EF_DIAG_CTRL 0x017C #define PLL_GH_DIAG_CTRL 0x0180 -#define TEST_CTRL 0x0184 -#define BIST_STAT 0x0188 -#define BIST_STAT2 0x018C -#define BIST_VID_PLL_AB_STAT 0x0190 -#define BIST_VID_PLL_CD_STAT 0x0194 -#define BIST_VID_PLL_EF_STAT 0x0198 -#define BIST_VID_PLL_GH_STAT 0x019C +#define TEST_CTRL 0x0184 +#define BIST_STAT 0x0188 +#define BIST_STAT2 0x018C +#define BIST_VID_PLL_AB_STAT 0x0190 +#define BIST_VID_PLL_CD_STAT 0x0194 +#define BIST_VID_PLL_EF_STAT 0x0198 +#define BIST_VID_PLL_GH_STAT 0x019C #define DLL_DIAG_CTRL 0x01A0 #define DEV_CH_ID_CTRL 0x01A4 #define ABIST_CTRL_STATUS 0x01A8 -#define ABIST_FREQ 0x01AC +#define ABIST_FREQ 0x01AC #define ABIST_GOERT_SHIFT 0x01B0 #define ABIST_COEF12 0x01B4 #define ABIST_COEF34 0x01B8 @@ -92,357 +92,357 @@ #define ABIST_CLAMP_E 0x01F4 #define ABIST_CLAMP_F 0x01F8 -/* Digital Video Encoder A Registers */ -#define DENC_A_REG_1 0x0200 -#define DENC_A_REG_2 0x0204 -#define DENC_A_REG_3 0x0208 -#define DENC_A_REG_4 0x020C -#define DENC_A_REG_5 0x0210 -#define DENC_A_REG_6 0x0214 -#define DENC_A_REG_7 0x0218 -#define DENC_A_REG_8 0x021C +/* Digital Video Encoder A Registers */ +#define DENC_A_REG_1 0x0200 +#define DENC_A_REG_2 0x0204 +#define DENC_A_REG_3 0x0208 +#define DENC_A_REG_4 0x020C +#define DENC_A_REG_5 0x0210 +#define DENC_A_REG_6 0x0214 +#define DENC_A_REG_7 0x0218 +#define DENC_A_REG_8 0x021C -/* Digital Video Encoder B Registers */ -#define DENC_B_REG_1 0x0300 -#define DENC_B_REG_2 0x0304 -#define DENC_B_REG_3 0x0308 -#define DENC_B_REG_4 0x030C -#define DENC_B_REG_5 0x0310 -#define DENC_B_REG_6 0x0314 -#define DENC_B_REG_7 0x0318 -#define DENC_B_REG_8 0x031C +/* Digital Video Encoder B Registers */ +#define DENC_B_REG_1 0x0300 +#define DENC_B_REG_2 0x0304 +#define DENC_B_REG_3 0x0308 +#define DENC_B_REG_4 0x030C +#define DENC_B_REG_5 0x0310 +#define DENC_B_REG_6 0x0314 +#define DENC_B_REG_7 0x0318 +#define DENC_B_REG_8 0x031C -/* Video Decoder A Registers */ -#define MODE_CTRL 0x1000 -#define OUT_CTRL1 0x1004 -#define OUT_CTRL_NS 0x1008 -#define GEN_STAT 0x100C -#define INT_STAT_MASK 0x1010 -#define LUMA_CTRL 0x1014 -#define CHROMA_CTRL 0x1018 -#define CRUSH_CTRL 0x101C -#define HORIZ_TIM_CTRL 0x1020 -#define VERT_TIM_CTRL 0x1024 -#define MISC_TIM_CTRL 0x1028 -#define FIELD_COUNT 0x102C -#define HSCALE_CTRL 0x1030 -#define VSCALE_CTRL 0x1034 -#define MAN_VGA_CTRL 0x1038 -#define MAN_AGC_CTRL 0x103C -#define DFE_CTRL1 0x1040 -#define DFE_CTRL2 0x1044 -#define DFE_CTRL3 0x1048 -#define PLL_CTRL 0x104C -#define PLL_CTRL_FAST 0x1050 -#define HTL_CTRL 0x1054 -#define SRC_CFG 0x1058 -#define SC_STEP_SIZE 0x105C -#define SC_CONVERGE_CTRL 0x1060 -#define SC_LOOP_CTRL 0x1064 -#define COMB_2D_HFS_CFG 0x1068 -#define COMB_2D_HFD_CFG 0x106C -#define COMB_2D_LF_CFG 0x1070 -#define COMB_2D_BLEND 0x1074 -#define COMB_MISC_CTRL 0x1078 +/* Video Decoder A Registers */ +#define MODE_CTRL 0x1000 +#define OUT_CTRL1 0x1004 +#define OUT_CTRL_NS 0x1008 +#define GEN_STAT 0x100C +#define INT_STAT_MASK 0x1010 +#define LUMA_CTRL 0x1014 +#define CHROMA_CTRL 0x1018 +#define CRUSH_CTRL 0x101C +#define HORIZ_TIM_CTRL 0x1020 +#define VERT_TIM_CTRL 0x1024 +#define MISC_TIM_CTRL 0x1028 +#define FIELD_COUNT 0x102C +#define HSCALE_CTRL 0x1030 +#define VSCALE_CTRL 0x1034 +#define MAN_VGA_CTRL 0x1038 +#define MAN_AGC_CTRL 0x103C +#define DFE_CTRL1 0x1040 +#define DFE_CTRL2 0x1044 +#define DFE_CTRL3 0x1048 +#define PLL_CTRL 0x104C +#define PLL_CTRL_FAST 0x1050 +#define HTL_CTRL 0x1054 +#define SRC_CFG 0x1058 +#define SC_STEP_SIZE 0x105C +#define SC_CONVERGE_CTRL 0x1060 +#define SC_LOOP_CTRL 0x1064 +#define COMB_2D_HFS_CFG 0x1068 +#define COMB_2D_HFD_CFG 0x106C +#define COMB_2D_LF_CFG 0x1070 +#define COMB_2D_BLEND 0x1074 +#define COMB_MISC_CTRL 0x1078 #define COMB_FLAT_THRESH_CTRL 0x107C -#define COMB_TEST 0x1080 -#define BP_MISC_CTRL 0x1084 -#define VCR_DET_CTRL 0x1088 -#define NOISE_DET_CTRL 0x108C +#define COMB_TEST 0x1080 +#define BP_MISC_CTRL 0x1084 +#define VCR_DET_CTRL 0x1088 +#define NOISE_DET_CTRL 0x108C #define COMB_FLAT_NOISE_CTRL 0x1090 -#define VERSION 0x11F8 -#define SOFT_RST_CTRL 0x11FC +#define VERSION 0x11F8 +#define SOFT_RST_CTRL 0x11FC -/* Video Decoder B Registers */ -#define VDEC_B_MODE_CTRL 0x1200 -#define VDEC_B_OUT_CTRL1 0x1204 -#define VDEC_B_OUT_CTRL_NS 0x1208 -#define VDEC_B_GEN_STAT 0x120C +/* Video Decoder B Registers */ +#define VDEC_B_MODE_CTRL 0x1200 +#define VDEC_B_OUT_CTRL1 0x1204 +#define VDEC_B_OUT_CTRL_NS 0x1208 +#define VDEC_B_GEN_STAT 0x120C #define VDEC_B_INT_STAT_MASK 0x1210 -#define VDEC_B_LUMA_CTRL 0x1214 -#define VDEC_B_CHROMA_CTRL 0x1218 -#define VDEC_B_CRUSH_CTRL 0x121C +#define VDEC_B_LUMA_CTRL 0x1214 +#define VDEC_B_CHROMA_CTRL 0x1218 +#define VDEC_B_CRUSH_CTRL 0x121C #define VDEC_B_HORIZ_TIM_CTRL 0x1220 #define VDEC_B_VERT_TIM_CTRL 0x1224 #define VDEC_B_MISC_TIM_CTRL 0x1228 -#define VDEC_B_FIELD_COUNT 0x122C -#define VDEC_B_HSCALE_CTRL 0x1230 -#define VDEC_B_VSCALE_CTRL 0x1234 -#define VDEC_B_MAN_VGA_CTRL 0x1238 -#define VDEC_B_MAN_AGC_CTRL 0x123C -#define VDEC_B_DFE_CTRL1 0x1240 -#define VDEC_B_DFE_CTRL2 0x1244 -#define VDEC_B_DFE_CTRL3 0x1248 -#define VDEC_B_PLL_CTRL 0x124C +#define VDEC_B_FIELD_COUNT 0x122C +#define VDEC_B_HSCALE_CTRL 0x1230 +#define VDEC_B_VSCALE_CTRL 0x1234 +#define VDEC_B_MAN_VGA_CTRL 0x1238 +#define VDEC_B_MAN_AGC_CTRL 0x123C +#define VDEC_B_DFE_CTRL1 0x1240 +#define VDEC_B_DFE_CTRL2 0x1244 +#define VDEC_B_DFE_CTRL3 0x1248 +#define VDEC_B_PLL_CTRL 0x124C #define VDEC_B_PLL_CTRL_FAST 0x1250 -#define VDEC_B_HTL_CTRL 0x1254 -#define VDEC_B_SRC_CFG 0x1258 -#define VDEC_B_SC_STEP_SIZE 0x125C +#define VDEC_B_HTL_CTRL 0x1254 +#define VDEC_B_SRC_CFG 0x1258 +#define VDEC_B_SC_STEP_SIZE 0x125C #define VDEC_B_SC_CONVERGE_CTRL 0x1260 -#define VDEC_B_SC_LOOP_CTRL 0x1264 +#define VDEC_B_SC_LOOP_CTRL 0x1264 #define VDEC_B_COMB_2D_HFS_CFG 0x1268 #define VDEC_B_COMB_2D_HFD_CFG 0x126C #define VDEC_B_COMB_2D_LF_CFG 0x1270 #define VDEC_B_COMB_2D_BLEND 0x1274 #define VDEC_B_COMB_MISC_CTRL 0x1278 -#define VDEC_B_COMB_FLAT_THRESH_CTRL 0x127C -#define VDEC_B_COMB_TEST 0x1280 -#define VDEC_B_BP_MISC_CTRL 0x1284 -#define VDEC_B_VCR_DET_CTRL 0x1288 +#define VDEC_B_COMB_FLAT_THRESH_CTRL 0x127C +#define VDEC_B_COMB_TEST 0x1280 +#define VDEC_B_BP_MISC_CTRL 0x1284 +#define VDEC_B_VCR_DET_CTRL 0x1288 #define VDEC_B_NOISE_DET_CTRL 0x128C #define VDEC_B_COMB_FLAT_NOISE_CTRL 0x1290 -#define VDEC_B_VERSION 0x13F8 +#define VDEC_B_VERSION 0x13F8 #define VDEC_B_SOFT_RST_CTRL 0x13FC /* Video Decoder C Registers */ -#define VDEC_C_MODE_CTRL 0x1400 -#define VDEC_C_OUT_CTRL1 0x1404 -#define VDEC_C_OUT_CTRL_NS 0x1408 -#define VDEC_C_GEN_STAT 0x140C +#define VDEC_C_MODE_CTRL 0x1400 +#define VDEC_C_OUT_CTRL1 0x1404 +#define VDEC_C_OUT_CTRL_NS 0x1408 +#define VDEC_C_GEN_STAT 0x140C #define VDEC_C_INT_STAT_MASK 0x1410 -#define VDEC_C_LUMA_CTRL 0x1414 -#define VDEC_C_CHROMA_CTRL 0x1418 -#define VDEC_C_CRUSH_CTRL 0x141C +#define VDEC_C_LUMA_CTRL 0x1414 +#define VDEC_C_CHROMA_CTRL 0x1418 +#define VDEC_C_CRUSH_CTRL 0x141C #define VDEC_C_HORIZ_TIM_CTRL 0x1420 #define VDEC_C_VERT_TIM_CTRL 0x1424 #define VDEC_C_MISC_TIM_CTRL 0x1428 -#define VDEC_C_FIELD_COUNT 0x142C -#define VDEC_C_HSCALE_CTRL 0x1430 -#define VDEC_C_VSCALE_CTRL 0x1434 -#define VDEC_C_MAN_VGA_CTRL 0x1438 -#define VDEC_C_MAN_AGC_CTRL 0x143C -#define VDEC_C_DFE_CTRL1 0x1440 -#define VDEC_C_DFE_CTRL2 0x1444 -#define VDEC_C_DFE_CTRL3 0x1448 -#define VDEC_C_PLL_CTRL 0x144C +#define VDEC_C_FIELD_COUNT 0x142C +#define VDEC_C_HSCALE_CTRL 0x1430 +#define VDEC_C_VSCALE_CTRL 0x1434 +#define VDEC_C_MAN_VGA_CTRL 0x1438 +#define VDEC_C_MAN_AGC_CTRL 0x143C +#define VDEC_C_DFE_CTRL1 0x1440 +#define VDEC_C_DFE_CTRL2 0x1444 +#define VDEC_C_DFE_CTRL3 0x1448 +#define VDEC_C_PLL_CTRL 0x144C #define VDEC_C_PLL_CTRL_FAST 0x1450 -#define VDEC_C_HTL_CTRL 0x1454 -#define VDEC_C_SRC_CFG 0x1458 -#define VDEC_C_SC_STEP_SIZE 0x145C +#define VDEC_C_HTL_CTRL 0x1454 +#define VDEC_C_SRC_CFG 0x1458 +#define VDEC_C_SC_STEP_SIZE 0x145C #define VDEC_C_SC_CONVERGE_CTRL 0x1460 -#define VDEC_C_SC_LOOP_CTRL 0x1464 +#define VDEC_C_SC_LOOP_CTRL 0x1464 #define VDEC_C_COMB_2D_HFS_CFG 0x1468 #define VDEC_C_COMB_2D_HFD_CFG 0x146C #define VDEC_C_COMB_2D_LF_CFG 0x1470 #define VDEC_C_COMB_2D_BLEND 0x1474 #define VDEC_C_COMB_MISC_CTRL 0x1478 -#define VDEC_C_COMB_FLAT_THRESH_CTRL 0x147C -#define VDEC_C_COMB_TEST 0x1480 -#define VDEC_C_BP_MISC_CTRL 0x1484 -#define VDEC_C_VCR_DET_CTRL 0x1488 +#define VDEC_C_COMB_FLAT_THRESH_CTRL 0x147C +#define VDEC_C_COMB_TEST 0x1480 +#define VDEC_C_BP_MISC_CTRL 0x1484 +#define VDEC_C_VCR_DET_CTRL 0x1488 #define VDEC_C_NOISE_DET_CTRL 0x148C #define VDEC_C_COMB_FLAT_NOISE_CTRL 0x1490 -#define VDEC_C_VERSION 0x15F8 +#define VDEC_C_VERSION 0x15F8 #define VDEC_C_SOFT_RST_CTRL 0x15FC /* Video Decoder D Registers */ -#define VDEC_D_MODE_CTRL 0x1600 -#define VDEC_D_OUT_CTRL1 0x1604 -#define VDEC_D_OUT_CTRL_NS 0x1608 -#define VDEC_D_GEN_STAT 0x160C +#define VDEC_D_MODE_CTRL 0x1600 +#define VDEC_D_OUT_CTRL1 0x1604 +#define VDEC_D_OUT_CTRL_NS 0x1608 +#define VDEC_D_GEN_STAT 0x160C #define VDEC_D_INT_STAT_MASK 0x1610 -#define VDEC_D_LUMA_CTRL 0x1614 -#define VDEC_D_CHROMA_CTRL 0x1618 -#define VDEC_D_CRUSH_CTRL 0x161C +#define VDEC_D_LUMA_CTRL 0x1614 +#define VDEC_D_CHROMA_CTRL 0x1618 +#define VDEC_D_CRUSH_CTRL 0x161C #define VDEC_D_HORIZ_TIM_CTRL 0x1620 #define VDEC_D_VERT_TIM_CTRL 0x1624 #define VDEC_D_MISC_TIM_CTRL 0x1628 -#define VDEC_D_FIELD_COUNT 0x162C -#define VDEC_D_HSCALE_CTRL 0x1630 -#define VDEC_D_VSCALE_CTRL 0x1634 -#define VDEC_D_MAN_VGA_CTRL 0x1638 -#define VDEC_D_MAN_AGC_CTRL 0x163C -#define VDEC_D_DFE_CTRL1 0x1640 -#define VDEC_D_DFE_CTRL2 0x1644 -#define VDEC_D_DFE_CTRL3 0x1648 -#define VDEC_D_PLL_CTRL 0x164C +#define VDEC_D_FIELD_COUNT 0x162C +#define VDEC_D_HSCALE_CTRL 0x1630 +#define VDEC_D_VSCALE_CTRL 0x1634 +#define VDEC_D_MAN_VGA_CTRL 0x1638 +#define VDEC_D_MAN_AGC_CTRL 0x163C +#define VDEC_D_DFE_CTRL1 0x1640 +#define VDEC_D_DFE_CTRL2 0x1644 +#define VDEC_D_DFE_CTRL3 0x1648 +#define VDEC_D_PLL_CTRL 0x164C #define VDEC_D_PLL_CTRL_FAST 0x1650 -#define VDEC_D_HTL_CTRL 0x1654 -#define VDEC_D_SRC_CFG 0x1658 -#define VDEC_D_SC_STEP_SIZE 0x165C +#define VDEC_D_HTL_CTRL 0x1654 +#define VDEC_D_SRC_CFG 0x1658 +#define VDEC_D_SC_STEP_SIZE 0x165C #define VDEC_D_SC_CONVERGE_CTRL 0x1660 -#define VDEC_D_SC_LOOP_CTRL 0x1664 +#define VDEC_D_SC_LOOP_CTRL 0x1664 #define VDEC_D_COMB_2D_HFS_CFG 0x1668 #define VDEC_D_COMB_2D_HFD_CFG 0x166C #define VDEC_D_COMB_2D_LF_CFG 0x1670 #define VDEC_D_COMB_2D_BLEND 0x1674 #define VDEC_D_COMB_MISC_CTRL 0x1678 -#define VDEC_D_COMB_FLAT_THRESH_CTRL 0x167C -#define VDEC_D_COMB_TEST 0x1680 -#define VDEC_D_BP_MISC_CTRL 0x1684 -#define VDEC_D_VCR_DET_CTRL 0x1688 +#define VDEC_D_COMB_FLAT_THRESH_CTRL 0x167C +#define VDEC_D_COMB_TEST 0x1680 +#define VDEC_D_BP_MISC_CTRL 0x1684 +#define VDEC_D_VCR_DET_CTRL 0x1688 #define VDEC_D_NOISE_DET_CTRL 0x168C #define VDEC_D_COMB_FLAT_NOISE_CTRL 0x1690 -#define VDEC_D_VERSION 0x17F8 +#define VDEC_D_VERSION 0x17F8 #define VDEC_D_SOFT_RST_CTRL 0x17FC /* Video Decoder E Registers */ -#define VDEC_E_MODE_CTRL 0x1800 -#define VDEC_E_OUT_CTRL1 0x1804 -#define VDEC_E_OUT_CTRL_NS 0x1808 -#define VDEC_E_GEN_STAT 0x180C +#define VDEC_E_MODE_CTRL 0x1800 +#define VDEC_E_OUT_CTRL1 0x1804 +#define VDEC_E_OUT_CTRL_NS 0x1808 +#define VDEC_E_GEN_STAT 0x180C #define VDEC_E_INT_STAT_MASK 0x1810 -#define VDEC_E_LUMA_CTRL 0x1814 -#define VDEC_E_CHROMA_CTRL 0x1818 -#define VDEC_E_CRUSH_CTRL 0x181C +#define VDEC_E_LUMA_CTRL 0x1814 +#define VDEC_E_CHROMA_CTRL 0x1818 +#define VDEC_E_CRUSH_CTRL 0x181C #define VDEC_E_HORIZ_TIM_CTRL 0x1820 #define VDEC_E_VERT_TIM_CTRL 0x1824 #define VDEC_E_MISC_TIM_CTRL 0x1828 -#define VDEC_E_FIELD_COUNT 0x182C -#define VDEC_E_HSCALE_CTRL 0x1830 -#define VDEC_E_VSCALE_CTRL 0x1834 -#define VDEC_E_MAN_VGA_CTRL 0x1838 -#define VDEC_E_MAN_AGC_CTRL 0x183C -#define VDEC_E_DFE_CTRL1 0x1840 -#define VDEC_E_DFE_CTRL2 0x1844 -#define VDEC_E_DFE_CTRL3 0x1848 -#define VDEC_E_PLL_CTRL 0x184C +#define VDEC_E_FIELD_COUNT 0x182C +#define VDEC_E_HSCALE_CTRL 0x1830 +#define VDEC_E_VSCALE_CTRL 0x1834 +#define VDEC_E_MAN_VGA_CTRL 0x1838 +#define VDEC_E_MAN_AGC_CTRL 0x183C +#define VDEC_E_DFE_CTRL1 0x1840 +#define VDEC_E_DFE_CTRL2 0x1844 +#define VDEC_E_DFE_CTRL3 0x1848 +#define VDEC_E_PLL_CTRL 0x184C #define VDEC_E_PLL_CTRL_FAST 0x1850 -#define VDEC_E_HTL_CTRL 0x1854 -#define VDEC_E_SRC_CFG 0x1858 -#define VDEC_E_SC_STEP_SIZE 0x185C +#define VDEC_E_HTL_CTRL 0x1854 +#define VDEC_E_SRC_CFG 0x1858 +#define VDEC_E_SC_STEP_SIZE 0x185C #define VDEC_E_SC_CONVERGE_CTRL 0x1860 -#define VDEC_E_SC_LOOP_CTRL 0x1864 +#define VDEC_E_SC_LOOP_CTRL 0x1864 #define VDEC_E_COMB_2D_HFS_CFG 0x1868 #define VDEC_E_COMB_2D_HFD_CFG 0x186C #define VDEC_E_COMB_2D_LF_CFG 0x1870 #define VDEC_E_COMB_2D_BLEND 0x1874 #define VDEC_E_COMB_MISC_CTRL 0x1878 -#define VDEC_E_COMB_FLAT_THRESH_CTRL 0x187C -#define VDEC_E_COMB_TEST 0x1880 -#define VDEC_E_BP_MISC_CTRL 0x1884 -#define VDEC_E_VCR_DET_CTRL 0x1888 +#define VDEC_E_COMB_FLAT_THRESH_CTRL 0x187C +#define VDEC_E_COMB_TEST 0x1880 +#define VDEC_E_BP_MISC_CTRL 0x1884 +#define VDEC_E_VCR_DET_CTRL 0x1888 #define VDEC_E_NOISE_DET_CTRL 0x188C #define VDEC_E_COMB_FLAT_NOISE_CTRL 0x1890 -#define VDEC_E_VERSION 0x19F8 +#define VDEC_E_VERSION 0x19F8 #define VDEC_E_SOFT_RST_CTRL 0x19FC /* Video Decoder F Registers */ -#define VDEC_F_MODE_CTRL 0x1A00 -#define VDEC_F_OUT_CTRL1 0x1A04 -#define VDEC_F_OUT_CTRL_NS 0x1A08 -#define VDEC_F_GEN_STAT 0x1A0C +#define VDEC_F_MODE_CTRL 0x1A00 +#define VDEC_F_OUT_CTRL1 0x1A04 +#define VDEC_F_OUT_CTRL_NS 0x1A08 +#define VDEC_F_GEN_STAT 0x1A0C #define VDEC_F_INT_STAT_MASK 0x1A10 -#define VDEC_F_LUMA_CTRL 0x1A14 -#define VDEC_F_CHROMA_CTRL 0x1A18 -#define VDEC_F_CRUSH_CTRL 0x1A1C +#define VDEC_F_LUMA_CTRL 0x1A14 +#define VDEC_F_CHROMA_CTRL 0x1A18 +#define VDEC_F_CRUSH_CTRL 0x1A1C #define VDEC_F_HORIZ_TIM_CTRL 0x1A20 #define VDEC_F_VERT_TIM_CTRL 0x1A24 #define VDEC_F_MISC_TIM_CTRL 0x1A28 -#define VDEC_F_FIELD_COUNT 0x1A2C -#define VDEC_F_HSCALE_CTRL 0x1A30 -#define VDEC_F_VSCALE_CTRL 0x1A34 -#define VDEC_F_MAN_VGA_CTRL 0x1A38 -#define VDEC_F_MAN_AGC_CTRL 0x1A3C -#define VDEC_F_DFE_CTRL1 0x1A40 -#define VDEC_F_DFE_CTRL2 0x1A44 -#define VDEC_F_DFE_CTRL3 0x1A48 -#define VDEC_F_PLL_CTRL 0x1A4C +#define VDEC_F_FIELD_COUNT 0x1A2C +#define VDEC_F_HSCALE_CTRL 0x1A30 +#define VDEC_F_VSCALE_CTRL 0x1A34 +#define VDEC_F_MAN_VGA_CTRL 0x1A38 +#define VDEC_F_MAN_AGC_CTRL 0x1A3C +#define VDEC_F_DFE_CTRL1 0x1A40 +#define VDEC_F_DFE_CTRL2 0x1A44 +#define VDEC_F_DFE_CTRL3 0x1A48 +#define VDEC_F_PLL_CTRL 0x1A4C #define VDEC_F_PLL_CTRL_FAST 0x1A50 -#define VDEC_F_HTL_CTRL 0x1A54 -#define VDEC_F_SRC_CFG 0x1A58 -#define VDEC_F_SC_STEP_SIZE 0x1A5C +#define VDEC_F_HTL_CTRL 0x1A54 +#define VDEC_F_SRC_CFG 0x1A58 +#define VDEC_F_SC_STEP_SIZE 0x1A5C #define VDEC_F_SC_CONVERGE_CTRL 0x1A60 -#define VDEC_F_SC_LOOP_CTRL 0x1A64 +#define VDEC_F_SC_LOOP_CTRL 0x1A64 #define VDEC_F_COMB_2D_HFS_CFG 0x1A68 #define VDEC_F_COMB_2D_HFD_CFG 0x1A6C #define VDEC_F_COMB_2D_LF_CFG 0x1A70 #define VDEC_F_COMB_2D_BLEND 0x1A74 #define VDEC_F_COMB_MISC_CTRL 0x1A78 -#define VDEC_F_COMB_FLAT_THRESH_CTRL 0x1A7C -#define VDEC_F_COMB_TEST 0x1A80 -#define VDEC_F_BP_MISC_CTRL 0x1A84 -#define VDEC_F_VCR_DET_CTRL 0x1A88 +#define VDEC_F_COMB_FLAT_THRESH_CTRL 0x1A7C +#define VDEC_F_COMB_TEST 0x1A80 +#define VDEC_F_BP_MISC_CTRL 0x1A84 +#define VDEC_F_VCR_DET_CTRL 0x1A88 #define VDEC_F_NOISE_DET_CTRL 0x1A8C #define VDEC_F_COMB_FLAT_NOISE_CTRL 0x1A90 -#define VDEC_F_VERSION 0x1BF8 +#define VDEC_F_VERSION 0x1BF8 #define VDEC_F_SOFT_RST_CTRL 0x1BFC /* Video Decoder G Registers */ -#define VDEC_G_MODE_CTRL 0x1C00 -#define VDEC_G_OUT_CTRL1 0x1C04 -#define VDEC_G_OUT_CTRL_NS 0x1C08 -#define VDEC_G_GEN_STAT 0x1C0C +#define VDEC_G_MODE_CTRL 0x1C00 +#define VDEC_G_OUT_CTRL1 0x1C04 +#define VDEC_G_OUT_CTRL_NS 0x1C08 +#define VDEC_G_GEN_STAT 0x1C0C #define VDEC_G_INT_STAT_MASK 0x1C10 -#define VDEC_G_LUMA_CTRL 0x1C14 -#define VDEC_G_CHROMA_CTRL 0x1C18 -#define VDEC_G_CRUSH_CTRL 0x1C1C +#define VDEC_G_LUMA_CTRL 0x1C14 +#define VDEC_G_CHROMA_CTRL 0x1C18 +#define VDEC_G_CRUSH_CTRL 0x1C1C #define VDEC_G_HORIZ_TIM_CTRL 0x1C20 #define VDEC_G_VERT_TIM_CTRL 0x1C24 #define VDEC_G_MISC_TIM_CTRL 0x1C28 -#define VDEC_G_FIELD_COUNT 0x1C2C -#define VDEC_G_HSCALE_CTRL 0x1C30 -#define VDEC_G_VSCALE_CTRL 0x1C34 -#define VDEC_G_MAN_VGA_CTRL 0x1C38 -#define VDEC_G_MAN_AGC_CTRL 0x1C3C -#define VDEC_G_DFE_CTRL1 0x1C40 -#define VDEC_G_DFE_CTRL2 0x1C44 -#define VDEC_G_DFE_CTRL3 0x1C48 -#define VDEC_G_PLL_CTRL 0x1C4C +#define VDEC_G_FIELD_COUNT 0x1C2C +#define VDEC_G_HSCALE_CTRL 0x1C30 +#define VDEC_G_VSCALE_CTRL 0x1C34 +#define VDEC_G_MAN_VGA_CTRL 0x1C38 +#define VDEC_G_MAN_AGC_CTRL 0x1C3C +#define VDEC_G_DFE_CTRL1 0x1C40 +#define VDEC_G_DFE_CTRL2 0x1C44 +#define VDEC_G_DFE_CTRL3 0x1C48 +#define VDEC_G_PLL_CTRL 0x1C4C #define VDEC_G_PLL_CTRL_FAST 0x1C50 -#define VDEC_G_HTL_CTRL 0x1C54 -#define VDEC_G_SRC_CFG 0x1C58 -#define VDEC_G_SC_STEP_SIZE 0x1C5C +#define VDEC_G_HTL_CTRL 0x1C54 +#define VDEC_G_SRC_CFG 0x1C58 +#define VDEC_G_SC_STEP_SIZE 0x1C5C #define VDEC_G_SC_CONVERGE_CTRL 0x1C60 -#define VDEC_G_SC_LOOP_CTRL 0x1C64 +#define VDEC_G_SC_LOOP_CTRL 0x1C64 #define VDEC_G_COMB_2D_HFS_CFG 0x1C68 #define VDEC_G_COMB_2D_HFD_CFG 0x1C6C #define VDEC_G_COMB_2D_LF_CFG 0x1C70 #define VDEC_G_COMB_2D_BLEND 0x1C74 #define VDEC_G_COMB_MISC_CTRL 0x1C78 -#define VDEC_G_COMB_FLAT_THRESH_CTRL 0x1C7C -#define VDEC_G_COMB_TEST 0x1C80 -#define VDEC_G_BP_MISC_CTRL 0x1C84 -#define VDEC_G_VCR_DET_CTRL 0x1C88 +#define VDEC_G_COMB_FLAT_THRESH_CTRL 0x1C7C +#define VDEC_G_COMB_TEST 0x1C80 +#define VDEC_G_BP_MISC_CTRL 0x1C84 +#define VDEC_G_VCR_DET_CTRL 0x1C88 #define VDEC_G_NOISE_DET_CTRL 0x1C8C #define VDEC_G_COMB_FLAT_NOISE_CTRL 0x1C90 -#define VDEC_G_VERSION 0x1DF8 +#define VDEC_G_VERSION 0x1DF8 #define VDEC_G_SOFT_RST_CTRL 0x1DFC -/* Video Decoder H Registers */ -#define VDEC_H_MODE_CTRL 0x1E00 -#define VDEC_H_OUT_CTRL1 0x1E04 -#define VDEC_H_OUT_CTRL_NS 0x1E08 -#define VDEC_H_GEN_STAT 0x1E0C +/* Video Decoder H Registers */ +#define VDEC_H_MODE_CTRL 0x1E00 +#define VDEC_H_OUT_CTRL1 0x1E04 +#define VDEC_H_OUT_CTRL_NS 0x1E08 +#define VDEC_H_GEN_STAT 0x1E0C #define VDEC_H_INT_STAT_MASK 0x1E1E -#define VDEC_H_LUMA_CTRL 0x1E14 -#define VDEC_H_CHROMA_CTRL 0x1E18 -#define VDEC_H_CRUSH_CTRL 0x1E1C +#define VDEC_H_LUMA_CTRL 0x1E14 +#define VDEC_H_CHROMA_CTRL 0x1E18 +#define VDEC_H_CRUSH_CTRL 0x1E1C #define VDEC_H_HORIZ_TIM_CTRL 0x1E20 #define VDEC_H_VERT_TIM_CTRL 0x1E24 #define VDEC_H_MISC_TIM_CTRL 0x1E28 -#define VDEC_H_FIELD_COUNT 0x1E2C -#define VDEC_H_HSCALE_CTRL 0x1E30 -#define VDEC_H_VSCALE_CTRL 0x1E34 -#define VDEC_H_MAN_VGA_CTRL 0x1E38 -#define VDEC_H_MAN_AGC_CTRL 0x1E3C -#define VDEC_H_DFE_CTRL1 0x1E40 -#define VDEC_H_DFE_CTRL2 0x1E44 -#define VDEC_H_DFE_CTRL3 0x1E48 -#define VDEC_H_PLL_CTRL 0x1E4C +#define VDEC_H_FIELD_COUNT 0x1E2C +#define VDEC_H_HSCALE_CTRL 0x1E30 +#define VDEC_H_VSCALE_CTRL 0x1E34 +#define VDEC_H_MAN_VGA_CTRL 0x1E38 +#define VDEC_H_MAN_AGC_CTRL 0x1E3C +#define VDEC_H_DFE_CTRL1 0x1E40 +#define VDEC_H_DFE_CTRL2 0x1E44 +#define VDEC_H_DFE_CTRL3 0x1E48 +#define VDEC_H_PLL_CTRL 0x1E4C #define VDEC_H_PLL_CTRL_FAST 0x1E50 -#define VDEC_H_HTL_CTRL 0x1E54 -#define VDEC_H_SRC_CFG 0x1E58 -#define VDEC_H_SC_STEP_SIZE 0x1E5C +#define VDEC_H_HTL_CTRL 0x1E54 +#define VDEC_H_SRC_CFG 0x1E58 +#define VDEC_H_SC_STEP_SIZE 0x1E5C #define VDEC_H_SC_CONVERGE_CTRL 0x1E60 -#define VDEC_H_SC_LOOP_CTRL 0x1E64 +#define VDEC_H_SC_LOOP_CTRL 0x1E64 #define VDEC_H_COMB_2D_HFS_CFG 0x1E68 #define VDEC_H_COMB_2D_HFD_CFG 0x1E6C #define VDEC_H_COMB_2D_LF_CFG 0x1E70 #define VDEC_H_COMB_2D_BLEND 0x1E74 #define VDEC_H_COMB_MISC_CTRL 0x1E78 -#define VDEC_H_COMB_FLAT_THRESH_CTRL 0x1E7C -#define VDEC_H_COMB_TEST 0x1E80 -#define VDEC_H_BP_MISC_CTRL 0x1E84 -#define VDEC_H_VCR_DET_CTRL 0x1E88 +#define VDEC_H_COMB_FLAT_THRESH_CTRL 0x1E7C +#define VDEC_H_COMB_TEST 0x1E80 +#define VDEC_H_BP_MISC_CTRL 0x1E84 +#define VDEC_H_VCR_DET_CTRL 0x1E88 #define VDEC_H_NOISE_DET_CTRL 0x1E8C #define VDEC_H_COMB_FLAT_NOISE_CTRL 0x1E90 -#define VDEC_H_VERSION 0x1FF8 +#define VDEC_H_VERSION 0x1FF8 #define VDEC_H_SOFT_RST_CTRL 0x1FFC /*****************************************************************************/ /* LUMA_CTRL register fields */ -#define VDEC_A_BRITE_CTRL 0x1014 +#define VDEC_A_BRITE_CTRL 0x1014 #define VDEC_A_CNTRST_CTRL 0x1015 #define VDEC_A_PEAK_SEL 0x1016 -- cgit v0.10.2 From 09c35440308138059e23a9a8e04f053094fb81a8 Mon Sep 17 00:00:00 2001 From: "Leonid V. Fedorenchik" Date: Sat, 22 Oct 2011 01:43:38 -0300 Subject: [media] cx25821-medusa-video.c: Fix comment Delete part of the comment that is not checked in code. Signed-off-by: Leonid V. Fedorenchik Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/cx25821/cx25821-medusa-video.c b/drivers/media/video/cx25821/cx25821-medusa-video.c index fc780d0..48c62c9 100644 --- a/drivers/media/video/cx25821/cx25821-medusa-video.c +++ b/drivers/media/video/cx25821/cx25821-medusa-video.c @@ -499,7 +499,7 @@ void medusa_set_resolution(struct cx25821_dev *dev, int width, mutex_lock(&dev->lock); - /* validate the width - cannot be negative */ + /* validate the width */ if (width > MAX_WIDTH) { pr_info("%s(): width %d > MAX_WIDTH %d ! resetting to MAX_WIDTH\n", __func__, width, MAX_WIDTH); -- cgit v0.10.2 From 49faae869fb1647b8201859602e11bed18230702 Mon Sep 17 00:00:00 2001 From: "Leonid V. Fedorenchik" Date: Sat, 22 Oct 2011 01:43:39 -0300 Subject: [media] cx25821-medusa-video.c: Move operators Plase operators in complex expressions at the end of the lines to preserve consistency. Signed-off-by: Leonid V. Fedorenchik Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/cx25821/cx25821-medusa-video.c b/drivers/media/video/cx25821/cx25821-medusa-video.c index 48c62c9..1ae0e8a 100644 --- a/drivers/media/video/cx25821/cx25821-medusa-video.c +++ b/drivers/media/video/cx25821/cx25821-medusa-video.c @@ -654,8 +654,8 @@ int medusa_set_brightness(struct cx25821_dev *dev, int brightness, int decoder) u32 val = 0, tmp = 0; mutex_lock(&dev->lock); - if ((brightness > VIDEO_PROCAMP_MAX) - || (brightness < VIDEO_PROCAMP_MIN)) { + if ((brightness > VIDEO_PROCAMP_MAX) || + (brightness < VIDEO_PROCAMP_MIN)) { mutex_unlock(&dev->lock); return -1; } @@ -743,8 +743,8 @@ int medusa_set_saturation(struct cx25821_dev *dev, int saturation, int decoder) mutex_lock(&dev->lock); - if ((saturation > VIDEO_PROCAMP_MAX) - || (saturation < VIDEO_PROCAMP_MIN)) { + if ((saturation > VIDEO_PROCAMP_MAX) || + (saturation < VIDEO_PROCAMP_MIN)) { mutex_unlock(&dev->lock); return -1; } -- cgit v0.10.2 From 14098bc73080fcb945423a4fd36eec0a89fb35bd Mon Sep 17 00:00:00 2001 From: "Leonid V. Fedorenchik" Date: Sat, 22 Oct 2011 01:43:40 -0300 Subject: [media] cx25821-medusa-video.c: Change line endings Change obscure line endings to less obscure ones. (improve readability) Signed-off-by: Leonid V. Fedorenchik Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/cx25821/cx25821-medusa-video.c b/drivers/media/video/cx25821/cx25821-medusa-video.c index 1ae0e8a..298a68d 100644 --- a/drivers/media/video/cx25821/cx25821-medusa-video.c +++ b/drivers/media/video/cx25821/cx25821-medusa-video.c @@ -99,82 +99,67 @@ static int medusa_initialize_ntsc(struct cx25821_dev *dev) for (i = 0; i < MAX_DECODERS; i++) { /* set video format NTSC-M */ - value = - cx25821_i2c_read(&dev->i2c_bus[0], MODE_CTRL + (0x200 * i), - &tmp); + value = cx25821_i2c_read(&dev->i2c_bus[0], + MODE_CTRL + (0x200 * i), &tmp); value &= 0xFFFFFFF0; /* enable the fast locking mode bit[16] */ value |= 0x10001; - ret_val = - cx25821_i2c_write(&dev->i2c_bus[0], MODE_CTRL + (0x200 * i), - value); + ret_val = cx25821_i2c_write(&dev->i2c_bus[0], + MODE_CTRL + (0x200 * i), value); /* resolution NTSC 720x480 */ - value = - cx25821_i2c_read(&dev->i2c_bus[0], - HORIZ_TIM_CTRL + (0x200 * i), &tmp); + value = cx25821_i2c_read(&dev->i2c_bus[0], + HORIZ_TIM_CTRL + (0x200 * i), &tmp); value &= 0x00C00C00; value |= 0x612D0074; - ret_val = - cx25821_i2c_write(&dev->i2c_bus[0], - HORIZ_TIM_CTRL + (0x200 * i), value); + ret_val = cx25821_i2c_write(&dev->i2c_bus[0], + HORIZ_TIM_CTRL + (0x200 * i), value); - value = - cx25821_i2c_read(&dev->i2c_bus[0], - VERT_TIM_CTRL + (0x200 * i), &tmp); + value = cx25821_i2c_read(&dev->i2c_bus[0], + VERT_TIM_CTRL + (0x200 * i), &tmp); value &= 0x00C00C00; value |= 0x1C1E001A; /* vblank_cnt + 2 to get camera ID */ - ret_val = - cx25821_i2c_write(&dev->i2c_bus[0], - VERT_TIM_CTRL + (0x200 * i), value); + ret_val = cx25821_i2c_write(&dev->i2c_bus[0], + VERT_TIM_CTRL + (0x200 * i), value); /* chroma subcarrier step size */ - ret_val = - cx25821_i2c_write(&dev->i2c_bus[0], - SC_STEP_SIZE + (0x200 * i), 0x43E00000); + ret_val = cx25821_i2c_write(&dev->i2c_bus[0], + SC_STEP_SIZE + (0x200 * i), 0x43E00000); /* enable VIP optional active */ - value = - cx25821_i2c_read(&dev->i2c_bus[0], - OUT_CTRL_NS + (0x200 * i), &tmp); + value = cx25821_i2c_read(&dev->i2c_bus[0], + OUT_CTRL_NS + (0x200 * i), &tmp); value &= 0xFFFBFFFF; value |= 0x00040000; - ret_val = - cx25821_i2c_write(&dev->i2c_bus[0], - OUT_CTRL_NS + (0x200 * i), value); + ret_val = cx25821_i2c_write(&dev->i2c_bus[0], + OUT_CTRL_NS + (0x200 * i), value); /* enable VIP optional active (VIP_OPT_AL) for direct output. */ - value = - cx25821_i2c_read(&dev->i2c_bus[0], OUT_CTRL1 + (0x200 * i), - &tmp); + value = cx25821_i2c_read(&dev->i2c_bus[0], + OUT_CTRL1 + (0x200 * i), &tmp); value &= 0xFFFBFFFF; value |= 0x00040000; - ret_val = - cx25821_i2c_write(&dev->i2c_bus[0], OUT_CTRL1 + (0x200 * i), - value); + ret_val = cx25821_i2c_write(&dev->i2c_bus[0], + OUT_CTRL1 + (0x200 * i), value); /* * clear VPRES_VERT_EN bit, fixes the chroma run away problem * when the input switching rate < 16 fields */ - value = - cx25821_i2c_read(&dev->i2c_bus[0], - MISC_TIM_CTRL + (0x200 * i), &tmp); + value = cx25821_i2c_read(&dev->i2c_bus[0], + MISC_TIM_CTRL + (0x200 * i), &tmp); /* disable special play detection */ value = setBitAtPos(value, 14); value = clearBitAtPos(value, 15); - ret_val = - cx25821_i2c_write(&dev->i2c_bus[0], - MISC_TIM_CTRL + (0x200 * i), value); + ret_val = cx25821_i2c_write(&dev->i2c_bus[0], + MISC_TIM_CTRL + (0x200 * i), value); /* set vbi_gate_en to 0 */ - value = - cx25821_i2c_read(&dev->i2c_bus[0], DFE_CTRL1 + (0x200 * i), - &tmp); + value = cx25821_i2c_read(&dev->i2c_bus[0], + DFE_CTRL1 + (0x200 * i), &tmp); value = clearBitAtPos(value, 29); - ret_val = - cx25821_i2c_write(&dev->i2c_bus[0], DFE_CTRL1 + (0x200 * i), - value); + ret_val = cx25821_i2c_write(&dev->i2c_bus[0], + DFE_CTRL1 + (0x200 * i), value); /* Enable the generation of blue field output if no video */ medusa_enable_bluefield_output(dev, i, 1); @@ -182,61 +167,49 @@ static int medusa_initialize_ntsc(struct cx25821_dev *dev) for (i = 0; i < MAX_ENCODERS; i++) { /* NTSC hclock */ - value = - cx25821_i2c_read(&dev->i2c_bus[0], - DENC_A_REG_1 + (0x100 * i), &tmp); + value = cx25821_i2c_read(&dev->i2c_bus[0], + DENC_A_REG_1 + (0x100 * i), &tmp); value &= 0xF000FC00; value |= 0x06B402D0; - ret_val = - cx25821_i2c_write(&dev->i2c_bus[0], - DENC_A_REG_1 + (0x100 * i), value); + ret_val = cx25821_i2c_write(&dev->i2c_bus[0], + DENC_A_REG_1 + (0x100 * i), value); /* burst begin and burst end */ - value = - cx25821_i2c_read(&dev->i2c_bus[0], - DENC_A_REG_2 + (0x100 * i), &tmp); + value = cx25821_i2c_read(&dev->i2c_bus[0], + DENC_A_REG_2 + (0x100 * i), &tmp); value &= 0xFF000000; value |= 0x007E9054; - ret_val = - cx25821_i2c_write(&dev->i2c_bus[0], - DENC_A_REG_2 + (0x100 * i), value); + ret_val = cx25821_i2c_write(&dev->i2c_bus[0], + DENC_A_REG_2 + (0x100 * i), value); - value = - cx25821_i2c_read(&dev->i2c_bus[0], - DENC_A_REG_3 + (0x100 * i), &tmp); + value = cx25821_i2c_read(&dev->i2c_bus[0], + DENC_A_REG_3 + (0x100 * i), &tmp); value &= 0xFC00FE00; value |= 0x00EC00F0; - ret_val = - cx25821_i2c_write(&dev->i2c_bus[0], - DENC_A_REG_3 + (0x100 * i), value); + ret_val = cx25821_i2c_write(&dev->i2c_bus[0], + DENC_A_REG_3 + (0x100 * i), value); /* set NTSC vblank, no phase alternation, 7.5 IRE pedestal */ - value = - cx25821_i2c_read(&dev->i2c_bus[0], - DENC_A_REG_4 + (0x100 * i), &tmp); + value = cx25821_i2c_read(&dev->i2c_bus[0], + DENC_A_REG_4 + (0x100 * i), &tmp); value &= 0x00FCFFFF; value |= 0x13020000; - ret_val = - cx25821_i2c_write(&dev->i2c_bus[0], - DENC_A_REG_4 + (0x100 * i), value); + ret_val = cx25821_i2c_write(&dev->i2c_bus[0], + DENC_A_REG_4 + (0x100 * i), value); - value = - cx25821_i2c_read(&dev->i2c_bus[0], - DENC_A_REG_5 + (0x100 * i), &tmp); + value = cx25821_i2c_read(&dev->i2c_bus[0], + DENC_A_REG_5 + (0x100 * i), &tmp); value &= 0xFFFF0000; value |= 0x0000E575; - ret_val = - cx25821_i2c_write(&dev->i2c_bus[0], - DENC_A_REG_5 + (0x100 * i), value); + ret_val = cx25821_i2c_write(&dev->i2c_bus[0], + DENC_A_REG_5 + (0x100 * i), value); - ret_val = - cx25821_i2c_write(&dev->i2c_bus[0], - DENC_A_REG_6 + (0x100 * i), 0x009A89C1); + ret_val = cx25821_i2c_write(&dev->i2c_bus[0], + DENC_A_REG_6 + (0x100 * i), 0x009A89C1); /* Subcarrier Increment */ - ret_val = - cx25821_i2c_write(&dev->i2c_bus[0], - DENC_A_REG_7 + (0x100 * i), 0x21F07C1F); + ret_val = cx25821_i2c_write(&dev->i2c_bus[0], + DENC_A_REG_7 + (0x100 * i), 0x21F07C1F); } /* set picture resolutions */ @@ -261,34 +234,27 @@ static int medusa_PALCombInit(struct cx25821_dev *dev, int dec) u32 value = 0, tmp = 0; /* Setup for 2D threshold */ - ret_val = - cx25821_i2c_write(&dev->i2c_bus[0], COMB_2D_HFS_CFG + (0x200 * dec), - 0x20002861); - ret_val = - cx25821_i2c_write(&dev->i2c_bus[0], COMB_2D_HFD_CFG + (0x200 * dec), - 0x20002861); - ret_val = - cx25821_i2c_write(&dev->i2c_bus[0], COMB_2D_LF_CFG + (0x200 * dec), - 0x200A1023); + ret_val = cx25821_i2c_write(&dev->i2c_bus[0], + COMB_2D_HFS_CFG + (0x200 * dec), 0x20002861); + ret_val = cx25821_i2c_write(&dev->i2c_bus[0], + COMB_2D_HFD_CFG + (0x200 * dec), 0x20002861); + ret_val = cx25821_i2c_write(&dev->i2c_bus[0], + COMB_2D_LF_CFG + (0x200 * dec), 0x200A1023); /* Setup flat chroma and luma thresholds */ - value = - cx25821_i2c_read(&dev->i2c_bus[0], - COMB_FLAT_THRESH_CTRL + (0x200 * dec), &tmp); + value = cx25821_i2c_read(&dev->i2c_bus[0], + COMB_FLAT_THRESH_CTRL + (0x200 * dec), &tmp); value &= 0x06230000; - ret_val = - cx25821_i2c_write(&dev->i2c_bus[0], - COMB_FLAT_THRESH_CTRL + (0x200 * dec), value); + ret_val = cx25821_i2c_write(&dev->i2c_bus[0], + COMB_FLAT_THRESH_CTRL + (0x200 * dec), value); /* set comb 2D blend */ - ret_val = - cx25821_i2c_write(&dev->i2c_bus[0], COMB_2D_BLEND + (0x200 * dec), - 0x210F0F0F); + ret_val = cx25821_i2c_write(&dev->i2c_bus[0], + COMB_2D_BLEND + (0x200 * dec), 0x210F0F0F); /* COMB MISC CONTROL */ - ret_val = - cx25821_i2c_write(&dev->i2c_bus[0], COMB_MISC_CTRL + (0x200 * dec), - 0x41120A7F); + ret_val = cx25821_i2c_write(&dev->i2c_bus[0], + COMB_MISC_CTRL + (0x200 * dec), 0x41120A7F); return ret_val; } @@ -304,83 +270,68 @@ static int medusa_initialize_pal(struct cx25821_dev *dev) for (i = 0; i < MAX_DECODERS; i++) { /* set video format PAL-BDGHI */ - value = - cx25821_i2c_read(&dev->i2c_bus[0], MODE_CTRL + (0x200 * i), - &tmp); + value = cx25821_i2c_read(&dev->i2c_bus[0], + MODE_CTRL + (0x200 * i), &tmp); value &= 0xFFFFFFF0; /* enable the fast locking mode bit[16] */ value |= 0x10004; - ret_val = - cx25821_i2c_write(&dev->i2c_bus[0], MODE_CTRL + (0x200 * i), - value); + ret_val = cx25821_i2c_write(&dev->i2c_bus[0], + MODE_CTRL + (0x200 * i), value); /* resolution PAL 720x576 */ - value = - cx25821_i2c_read(&dev->i2c_bus[0], - HORIZ_TIM_CTRL + (0x200 * i), &tmp); + value = cx25821_i2c_read(&dev->i2c_bus[0], + HORIZ_TIM_CTRL + (0x200 * i), &tmp); value &= 0x00C00C00; value |= 0x632D007D; - ret_val = - cx25821_i2c_write(&dev->i2c_bus[0], - HORIZ_TIM_CTRL + (0x200 * i), value); + ret_val = cx25821_i2c_write(&dev->i2c_bus[0], + HORIZ_TIM_CTRL + (0x200 * i), value); /* vblank656_cnt=x26, vactive_cnt=240h, vblank_cnt=x24 */ - value = - cx25821_i2c_read(&dev->i2c_bus[0], - VERT_TIM_CTRL + (0x200 * i), &tmp); + value = cx25821_i2c_read(&dev->i2c_bus[0], + VERT_TIM_CTRL + (0x200 * i), &tmp); value &= 0x00C00C00; value |= 0x28240026; /* vblank_cnt + 2 to get camera ID */ - ret_val = - cx25821_i2c_write(&dev->i2c_bus[0], - VERT_TIM_CTRL + (0x200 * i), value); + ret_val = cx25821_i2c_write(&dev->i2c_bus[0], + VERT_TIM_CTRL + (0x200 * i), value); /* chroma subcarrier step size */ - ret_val = - cx25821_i2c_write(&dev->i2c_bus[0], - SC_STEP_SIZE + (0x200 * i), 0x5411E2D0); + ret_val = cx25821_i2c_write(&dev->i2c_bus[0], + SC_STEP_SIZE + (0x200 * i), 0x5411E2D0); /* enable VIP optional active */ - value = - cx25821_i2c_read(&dev->i2c_bus[0], - OUT_CTRL_NS + (0x200 * i), &tmp); + value = cx25821_i2c_read(&dev->i2c_bus[0], + OUT_CTRL_NS + (0x200 * i), &tmp); value &= 0xFFFBFFFF; value |= 0x00040000; - ret_val = - cx25821_i2c_write(&dev->i2c_bus[0], - OUT_CTRL_NS + (0x200 * i), value); + ret_val = cx25821_i2c_write(&dev->i2c_bus[0], + OUT_CTRL_NS + (0x200 * i), value); /* enable VIP optional active (VIP_OPT_AL) for direct output. */ - value = - cx25821_i2c_read(&dev->i2c_bus[0], OUT_CTRL1 + (0x200 * i), - &tmp); + value = cx25821_i2c_read(&dev->i2c_bus[0], + OUT_CTRL1 + (0x200 * i), &tmp); value &= 0xFFFBFFFF; value |= 0x00040000; - ret_val = - cx25821_i2c_write(&dev->i2c_bus[0], OUT_CTRL1 + (0x200 * i), - value); + ret_val = cx25821_i2c_write(&dev->i2c_bus[0], + OUT_CTRL1 + (0x200 * i), value); /* * clear VPRES_VERT_EN bit, fixes the chroma run away problem * when the input switching rate < 16 fields */ - value = - cx25821_i2c_read(&dev->i2c_bus[0], - MISC_TIM_CTRL + (0x200 * i), &tmp); + value = cx25821_i2c_read(&dev->i2c_bus[0], + MISC_TIM_CTRL + (0x200 * i), &tmp); /* disable special play detection */ value = setBitAtPos(value, 14); value = clearBitAtPos(value, 15); - ret_val = - cx25821_i2c_write(&dev->i2c_bus[0], - MISC_TIM_CTRL + (0x200 * i), value); + ret_val = cx25821_i2c_write(&dev->i2c_bus[0], + MISC_TIM_CTRL + (0x200 * i), value); /* set vbi_gate_en to 0 */ - value = - cx25821_i2c_read(&dev->i2c_bus[0], DFE_CTRL1 + (0x200 * i), - &tmp); + value = cx25821_i2c_read(&dev->i2c_bus[0], + DFE_CTRL1 + (0x200 * i), &tmp); value = clearBitAtPos(value, 29); - ret_val = - cx25821_i2c_write(&dev->i2c_bus[0], DFE_CTRL1 + (0x200 * i), - value); + ret_val = cx25821_i2c_write(&dev->i2c_bus[0], + DFE_CTRL1 + (0x200 * i), value); medusa_PALCombInit(dev, i); @@ -390,62 +341,50 @@ static int medusa_initialize_pal(struct cx25821_dev *dev) for (i = 0; i < MAX_ENCODERS; i++) { /* PAL hclock */ - value = - cx25821_i2c_read(&dev->i2c_bus[0], - DENC_A_REG_1 + (0x100 * i), &tmp); + value = cx25821_i2c_read(&dev->i2c_bus[0], + DENC_A_REG_1 + (0x100 * i), &tmp); value &= 0xF000FC00; value |= 0x06C002D0; - ret_val = - cx25821_i2c_write(&dev->i2c_bus[0], - DENC_A_REG_1 + (0x100 * i), value); + ret_val = cx25821_i2c_write(&dev->i2c_bus[0], + DENC_A_REG_1 + (0x100 * i), value); /* burst begin and burst end */ - value = - cx25821_i2c_read(&dev->i2c_bus[0], - DENC_A_REG_2 + (0x100 * i), &tmp); + value = cx25821_i2c_read(&dev->i2c_bus[0], + DENC_A_REG_2 + (0x100 * i), &tmp); value &= 0xFF000000; value |= 0x007E9754; - ret_val = - cx25821_i2c_write(&dev->i2c_bus[0], - DENC_A_REG_2 + (0x100 * i), value); + ret_val = cx25821_i2c_write(&dev->i2c_bus[0], + DENC_A_REG_2 + (0x100 * i), value); /* hblank and vactive */ - value = - cx25821_i2c_read(&dev->i2c_bus[0], - DENC_A_REG_3 + (0x100 * i), &tmp); + value = cx25821_i2c_read(&dev->i2c_bus[0], + DENC_A_REG_3 + (0x100 * i), &tmp); value &= 0xFC00FE00; value |= 0x00FC0120; - ret_val = - cx25821_i2c_write(&dev->i2c_bus[0], - DENC_A_REG_3 + (0x100 * i), value); + ret_val = cx25821_i2c_write(&dev->i2c_bus[0], + DENC_A_REG_3 + (0x100 * i), value); /* set PAL vblank, phase alternation, 0 IRE pedestal */ - value = - cx25821_i2c_read(&dev->i2c_bus[0], - DENC_A_REG_4 + (0x100 * i), &tmp); + value = cx25821_i2c_read(&dev->i2c_bus[0], + DENC_A_REG_4 + (0x100 * i), &tmp); value &= 0x00FCFFFF; value |= 0x14010000; - ret_val = - cx25821_i2c_write(&dev->i2c_bus[0], - DENC_A_REG_4 + (0x100 * i), value); + ret_val = cx25821_i2c_write(&dev->i2c_bus[0], + DENC_A_REG_4 + (0x100 * i), value); - value = - cx25821_i2c_read(&dev->i2c_bus[0], - DENC_A_REG_5 + (0x100 * i), &tmp); + value = cx25821_i2c_read(&dev->i2c_bus[0], + DENC_A_REG_5 + (0x100 * i), &tmp); value &= 0xFFFF0000; value |= 0x0000F078; - ret_val = - cx25821_i2c_write(&dev->i2c_bus[0], - DENC_A_REG_5 + (0x100 * i), value); + ret_val = cx25821_i2c_write(&dev->i2c_bus[0], + DENC_A_REG_5 + (0x100 * i), value); - ret_val = - cx25821_i2c_write(&dev->i2c_bus[0], - DENC_A_REG_6 + (0x100 * i), 0x00A493CF); + ret_val = cx25821_i2c_write(&dev->i2c_bus[0], + DENC_A_REG_6 + (0x100 * i), 0x00A493CF); /* Subcarrier Increment */ - ret_val = - cx25821_i2c_write(&dev->i2c_bus[0], - DENC_A_REG_7 + (0x100 * i), 0x2A098ACB); + ret_val = cx25821_i2c_write(&dev->i2c_bus[0], + DENC_A_REG_7 + (0x100 * i), 0x2A098ACB); } /* set picture resolutions */ @@ -543,12 +482,10 @@ void medusa_set_resolution(struct cx25821_dev *dev, int width, for (; decoder < decoder_count; decoder++) { /* write scaling values for each decoder */ - ret_val = - cx25821_i2c_write(&dev->i2c_bus[0], - HSCALE_CTRL + (0x200 * decoder), hscale); - ret_val = - cx25821_i2c_write(&dev->i2c_bus[0], - VSCALE_CTRL + (0x200 * decoder), vscale); + ret_val = cx25821_i2c_write(&dev->i2c_bus[0], + HSCALE_CTRL + (0x200 * decoder), hscale); + ret_val = cx25821_i2c_write(&dev->i2c_bus[0], + VSCALE_CTRL + (0x200 * decoder), vscale); } mutex_unlock(&dev->lock); @@ -606,8 +543,8 @@ static void medusa_set_decoderduration(struct cx25821_dev *dev, int decoder, } /* Map to Medusa register setting */ -static int mapM(int srcMin, - int srcMax, int srcVal, int dstMin, int dstMax, int *dstVal) +static int mapM(int srcMin, int srcMax, int srcVal, int dstMin, int dstMax, + int *dstVal) { int numerator; int denominator; @@ -659,18 +596,14 @@ int medusa_set_brightness(struct cx25821_dev *dev, int brightness, int decoder) mutex_unlock(&dev->lock); return -1; } - ret_val = - mapM(VIDEO_PROCAMP_MIN, VIDEO_PROCAMP_MAX, brightness, - SIGNED_BYTE_MIN, SIGNED_BYTE_MAX, &value); + ret_val = mapM(VIDEO_PROCAMP_MIN, VIDEO_PROCAMP_MAX, brightness, + SIGNED_BYTE_MIN, SIGNED_BYTE_MAX, &value); value = convert_to_twos(value, 8); - val = - cx25821_i2c_read(&dev->i2c_bus[0], - VDEC_A_BRITE_CTRL + (0x200 * decoder), &tmp); + val = cx25821_i2c_read(&dev->i2c_bus[0], + VDEC_A_BRITE_CTRL + (0x200 * decoder), &tmp); val &= 0xFFFFFF00; - ret_val |= - cx25821_i2c_write(&dev->i2c_bus[0], - VDEC_A_BRITE_CTRL + (0x200 * decoder), - val | value); + ret_val |= cx25821_i2c_write(&dev->i2c_bus[0], + VDEC_A_BRITE_CTRL + (0x200 * decoder), val | value); mutex_unlock(&dev->lock); return ret_val; } @@ -688,17 +621,13 @@ int medusa_set_contrast(struct cx25821_dev *dev, int contrast, int decoder) return -1; } - ret_val = - mapM(VIDEO_PROCAMP_MIN, VIDEO_PROCAMP_MAX, contrast, - UNSIGNED_BYTE_MIN, UNSIGNED_BYTE_MAX, &value); - val = - cx25821_i2c_read(&dev->i2c_bus[0], - VDEC_A_CNTRST_CTRL + (0x200 * decoder), &tmp); + ret_val = mapM(VIDEO_PROCAMP_MIN, VIDEO_PROCAMP_MAX, contrast, + UNSIGNED_BYTE_MIN, UNSIGNED_BYTE_MAX, &value); + val = cx25821_i2c_read(&dev->i2c_bus[0], + VDEC_A_CNTRST_CTRL + (0x200 * decoder), &tmp); val &= 0xFFFFFF00; - ret_val |= - cx25821_i2c_write(&dev->i2c_bus[0], - VDEC_A_CNTRST_CTRL + (0x200 * decoder), - val | value); + ret_val |= cx25821_i2c_write(&dev->i2c_bus[0], + VDEC_A_CNTRST_CTRL + (0x200 * decoder), val | value); mutex_unlock(&dev->lock); return ret_val; @@ -717,19 +646,16 @@ int medusa_set_hue(struct cx25821_dev *dev, int hue, int decoder) return -1; } - ret_val = - mapM(VIDEO_PROCAMP_MIN, VIDEO_PROCAMP_MAX, hue, SIGNED_BYTE_MIN, - SIGNED_BYTE_MAX, &value); + ret_val = mapM(VIDEO_PROCAMP_MIN, VIDEO_PROCAMP_MAX, hue, + SIGNED_BYTE_MIN, SIGNED_BYTE_MAX, &value); value = convert_to_twos(value, 8); - val = - cx25821_i2c_read(&dev->i2c_bus[0], - VDEC_A_HUE_CTRL + (0x200 * decoder), &tmp); + val = cx25821_i2c_read(&dev->i2c_bus[0], + VDEC_A_HUE_CTRL + (0x200 * decoder), &tmp); val &= 0xFFFFFF00; - ret_val |= - cx25821_i2c_write(&dev->i2c_bus[0], - VDEC_A_HUE_CTRL + (0x200 * decoder), val | value); + ret_val |= cx25821_i2c_write(&dev->i2c_bus[0], + VDEC_A_HUE_CTRL + (0x200 * decoder), val | value); mutex_unlock(&dev->lock); return ret_val; @@ -749,27 +675,20 @@ int medusa_set_saturation(struct cx25821_dev *dev, int saturation, int decoder) return -1; } - ret_val = - mapM(VIDEO_PROCAMP_MIN, VIDEO_PROCAMP_MAX, saturation, - UNSIGNED_BYTE_MIN, UNSIGNED_BYTE_MAX, &value); + ret_val = mapM(VIDEO_PROCAMP_MIN, VIDEO_PROCAMP_MAX, saturation, + UNSIGNED_BYTE_MIN, UNSIGNED_BYTE_MAX, &value); - val = - cx25821_i2c_read(&dev->i2c_bus[0], - VDEC_A_USAT_CTRL + (0x200 * decoder), &tmp); + val = cx25821_i2c_read(&dev->i2c_bus[0], + VDEC_A_USAT_CTRL + (0x200 * decoder), &tmp); val &= 0xFFFFFF00; - ret_val |= - cx25821_i2c_write(&dev->i2c_bus[0], - VDEC_A_USAT_CTRL + (0x200 * decoder), - val | value); - - val = - cx25821_i2c_read(&dev->i2c_bus[0], - VDEC_A_VSAT_CTRL + (0x200 * decoder), &tmp); + ret_val |= cx25821_i2c_write(&dev->i2c_bus[0], + VDEC_A_USAT_CTRL + (0x200 * decoder), val | value); + + val = cx25821_i2c_read(&dev->i2c_bus[0], + VDEC_A_VSAT_CTRL + (0x200 * decoder), &tmp); val &= 0xFFFFFF00; - ret_val |= - cx25821_i2c_write(&dev->i2c_bus[0], - VDEC_A_VSAT_CTRL + (0x200 * decoder), - val | value); + ret_val |= cx25821_i2c_write(&dev->i2c_bus[0], + VDEC_A_VSAT_CTRL + (0x200 * decoder), val | value); mutex_unlock(&dev->lock); return ret_val; @@ -830,9 +749,8 @@ int medusa_video_init(struct cx25821_dev *dev) /* select AFE clock to output mode */ value = cx25821_i2c_read(&dev->i2c_bus[0], AFE_AB_DIAG_CTRL, &tmp); value &= 0x83FFFFFF; - ret_val = - cx25821_i2c_write(&dev->i2c_bus[0], AFE_AB_DIAG_CTRL, - value | 0x10000000); + ret_val = cx25821_i2c_write(&dev->i2c_bus[0], AFE_AB_DIAG_CTRL, + value | 0x10000000); if (ret_val < 0) goto error; -- cgit v0.10.2 From 3940de7482be50f7071224c0f7812c6db1e132bd Mon Sep 17 00:00:00 2001 From: "Leonid V. Fedorenchik" Date: Sat, 22 Oct 2011 01:43:41 -0300 Subject: [media] cx25821-video-upstream-ch2.c: Line up comments Line up comments to match indent of surrounding statements. Signed-off-by: Leonid V. Fedorenchik Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/cx25821/cx25821-video-upstream-ch2.c b/drivers/media/video/cx25821/cx25821-video-upstream-ch2.c index 2a724dd..94e235f 100644 --- a/drivers/media/video/cx25821/cx25821-video-upstream-ch2.c +++ b/drivers/media/video/cx25821/cx25821-video-upstream-ch2.c @@ -173,7 +173,7 @@ int cx25821_risc_buffer_upstream_ch2(struct cx25821_dev *dev, fifo_enable = FIFO_DISABLE; - /* Even field */ + /* Even field */ rp = cx25821_risc_field_upstream_ch2(dev, rp, dev->_data_buf_phys_addr_ch2 + databuf_offset, bottom_offset, 0x200, bpl, singlefield_lines, @@ -189,9 +189,9 @@ int cx25821_risc_buffer_upstream_ch2(struct cx25821_dev *dev, } /* - Loop to 2ndFrameRISC or to Start of - Risc program & generate IRQ - */ + * Loop to 2ndFrameRISC or to Start of + * Risc program & generate IRQ + */ *(rp++) = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | risc_flag); *(rp++) = cpu_to_le32(risc_phys_jump_addr); *(rp++) = cpu_to_le32(0); -- cgit v0.10.2 From 2a4492d8223b7fef53d293b30db2141dcefb6de1 Mon Sep 17 00:00:00 2001 From: "Leonid V. Fedorenchik" Date: Sat, 22 Oct 2011 01:43:42 -0300 Subject: [media] cx25821-video-upstream-ch2.c: Fix indent Change indent of statements with (less than 8) spaces to indent with tabs. Signed-off-by: Leonid V. Fedorenchik Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/cx25821/cx25821-video-upstream-ch2.c b/drivers/media/video/cx25821/cx25821-video-upstream-ch2.c index 94e235f..af816a8 100644 --- a/drivers/media/video/cx25821/cx25821-video-upstream-ch2.c +++ b/drivers/media/video/cx25821/cx25821-video-upstream-ch2.c @@ -85,7 +85,7 @@ static __le32 *cx25821_risc_field_upstream_ch2(struct cx25821_dev *dev, { unsigned int line, i; struct sram_channel *sram_ch = - dev->channels[dev->_channel2_upstream_select].sram_channels; + dev->channels[dev->_channel2_upstream_select].sram_channels; int dist_betwn_starts = bpl * 2; /* sync instruction */ @@ -203,7 +203,7 @@ int cx25821_risc_buffer_upstream_ch2(struct cx25821_dev *dev, void cx25821_stop_upstream_video_ch2(struct cx25821_dev *dev) { struct sram_channel *sram_ch = - dev->channels[VID_UPSTREAM_SRAM_CHANNEL_J].sram_channels; + dev->channels[VID_UPSTREAM_SRAM_CHANNEL_J].sram_channels; u32 tmp = 0; if (!dev->_is_running_ch2) { @@ -325,7 +325,7 @@ int cx25821_get_frame_ch2(struct cx25821_dev *dev, struct sram_channel *sram_ch) && dev->_data_buf_virt_addr_ch2 != NULL) { memcpy((void *)(dev->_data_buf_virt_addr_ch2 + frame_offset / 4), mybuf, - vfs_read_retval); + vfs_read_retval); } file_offset += vfs_read_retval; @@ -419,7 +419,7 @@ int cx25821_openfile_ch2(struct cx25821_dev *dev, struct sram_channel *sram_ch) memcpy((void *)(dev-> _data_buf_virt_addr_ch2 + offset / 4), mybuf, - vfs_read_retval); + vfs_read_retval); } offset += vfs_read_retval; @@ -563,8 +563,8 @@ int cx25821_video_upstream_irq_ch2(struct cx25821_dev *dev, int chan_num, else line_size_in_bytes = Y422_LINE_SZ; risc_phys_jump_addr = - dev->_dma_phys_start_addr_ch2 + - odd_risc_prog_size; + dev->_dma_phys_start_addr_ch2 + + odd_risc_prog_size; rp = cx25821_update_riscprogram_ch2(dev, dev->_dma_virt_start_addr_ch2, -- cgit v0.10.2 From 3a59fab41b9935b2e52118b331e71078aec97676 Mon Sep 17 00:00:00 2001 From: "Leonid V. Fedorenchik" Date: Sat, 22 Oct 2011 01:43:43 -0300 Subject: [media] cx25821-video-upsstream-ch2.c: Move operators Move operators in complex expressions to the end of the lines to preserve consistency. Signed-off-by: Leonid V. Fedorenchik Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/cx25821/cx25821-video-upstream-ch2.c b/drivers/media/video/cx25821/cx25821-video-upstream-ch2.c index af816a8..53927e8 100644 --- a/drivers/media/video/cx25821/cx25821-video-upstream-ch2.c +++ b/drivers/media/video/cx25821/cx25821-video-upstream-ch2.c @@ -65,9 +65,8 @@ static __le32 *cx25821_update_riscprogram_ch2(struct cx25821_dev *dev, *(rp++) = cpu_to_le32(dev->_data_buf_phys_addr_ch2 + offset); *(rp++) = cpu_to_le32(0); /* bits 63-32 */ - if ((lines <= NTSC_FIELD_HEIGHT) - || (line < (NTSC_FIELD_HEIGHT - 1)) - || !(dev->_isNTSC_ch2)) { + if ((lines <= NTSC_FIELD_HEIGHT) || + (line < (NTSC_FIELD_HEIGHT - 1)) || !(dev->_isNTSC_ch2)) { offset += dist_betwn_starts; } } @@ -103,9 +102,8 @@ static __le32 *cx25821_risc_field_upstream_ch2(struct cx25821_dev *dev, *(rp++) = cpu_to_le32(databuf_phys_addr + offset); *(rp++) = cpu_to_le32(0); /* bits 63-32 */ - if ((lines <= NTSC_FIELD_HEIGHT) - || (line < (NTSC_FIELD_HEIGHT - 1)) - || !(dev->_isNTSC_ch2)) { + if ((lines <= NTSC_FIELD_HEIGHT) || + (line < (NTSC_FIELD_HEIGHT - 1)) || !(dev->_isNTSC_ch2)) { offset += dist_betwn_starts; } @@ -413,9 +411,9 @@ int cx25821_openfile_ch2(struct cx25821_dev *dev, struct sram_channel *sram_ch) vfs_read_retval = vfs_read(myfile, mybuf, line_size, &pos); - if (vfs_read_retval > 0 - && vfs_read_retval == line_size - && dev->_data_buf_virt_addr_ch2 != NULL) { + if (vfs_read_retval > 0 && + vfs_read_retval == line_size && + dev->_data_buf_virt_addr_ch2 != NULL) { memcpy((void *)(dev-> _data_buf_virt_addr_ch2 + offset / 4), mybuf, -- cgit v0.10.2 From df253423d41d377b353964b8a3343df4507fda7c Mon Sep 17 00:00:00 2001 From: "Leonid V. Fedorenchik" Date: Sat, 22 Oct 2011 01:43:44 -0300 Subject: [media] cx25821-video-upstream-ch2.c: Remove braces Remove unnecessary curly braces around single if statement. Signed-off-by: Leonid V. Fedorenchik Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/cx25821/cx25821-video-upstream-ch2.c b/drivers/media/video/cx25821/cx25821-video-upstream-ch2.c index 53927e8..1e452b8 100644 --- a/drivers/media/video/cx25821/cx25821-video-upstream-ch2.c +++ b/drivers/media/video/cx25821/cx25821-video-upstream-ch2.c @@ -610,11 +610,9 @@ static irqreturn_t cx25821_upstream_irq_ch2(int irq, void *dev_id) vid_status = cx_read(sram_ch->int_stat); /* Only deal with our interrupt */ - if (vid_status) { - handled = - cx25821_video_upstream_irq_ch2(dev, channel_num, - vid_status); - } + if (vid_status) + handled = cx25821_video_upstream_irq_ch2(dev, channel_num, + vid_status); if (handled < 0) cx25821_stop_upstream_video_ch2(dev); -- cgit v0.10.2 From 85b7982d16397d8677e96c0f2b1776c50bf0cfc5 Mon Sep 17 00:00:00 2001 From: "Leonid V. Fedorenchik" Date: Sat, 22 Oct 2011 01:43:45 -0300 Subject: [media] cx25821-video-upstream-ch2.c: Change line endings Change obscure line endings to less obscure ones. (improve readability) Signed-off-by: Leonid V. Fedorenchik Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/cx25821/cx25821-video-upstream-ch2.c b/drivers/media/video/cx25821/cx25821-video-upstream-ch2.c index 1e452b8..6401ce8 100644 --- a/drivers/media/video/cx25821/cx25821-video-upstream-ch2.c +++ b/drivers/media/video/cx25821/cx25821-video-upstream-ch2.c @@ -260,9 +260,8 @@ int cx25821_get_frame_ch2(struct cx25821_dev *dev, struct sram_channel *sram_ch) struct file *myfile; int frame_index_temp = dev->_frame_index_ch2; int i = 0; - int line_size = - (dev->_pixel_format_ch2 == - PIXEL_FRMT_411) ? Y411_LINE_SZ : Y422_LINE_SZ; + int line_size = (dev->_pixel_format_ch2 == PIXEL_FRMT_411) ? + Y411_LINE_SZ : Y422_LINE_SZ; int frame_size = 0; int frame_offset = 0; ssize_t vfs_read_retval = 0; @@ -275,14 +274,11 @@ int cx25821_get_frame_ch2(struct cx25821_dev *dev, struct sram_channel *sram_ch) return 0; if (dev->_isNTSC_ch2) { - frame_size = - (line_size == - Y411_LINE_SZ) ? FRAME_SIZE_NTSC_Y411 : - FRAME_SIZE_NTSC_Y422; + frame_size = (line_size == Y411_LINE_SZ) ? + FRAME_SIZE_NTSC_Y411 : FRAME_SIZE_NTSC_Y422; } else { - frame_size = - (line_size == - Y411_LINE_SZ) ? FRAME_SIZE_PAL_Y411 : FRAME_SIZE_PAL_Y422; + frame_size = (line_size == Y411_LINE_SZ) ? + FRAME_SIZE_PAL_Y411 : FRAME_SIZE_PAL_Y422; } frame_offset = (frame_index_temp > 0) ? frame_size : 0; @@ -316,8 +312,8 @@ int cx25821_get_frame_ch2(struct cx25821_dev *dev, struct sram_channel *sram_ch) for (i = 0; i < dev->_lines_count_ch2; i++) { pos = file_offset; - vfs_read_retval = - vfs_read(myfile, mybuf, line_size, &pos); + vfs_read_retval = vfs_read(myfile, mybuf, line_size, + &pos); if (vfs_read_retval > 0 && vfs_read_retval == line_size && dev->_data_buf_virt_addr_ch2 != NULL) { @@ -339,8 +335,8 @@ int cx25821_get_frame_ch2(struct cx25821_dev *dev, struct sram_channel *sram_ch) if (i > 0) dev->_frame_count_ch2++; - dev->_file_status_ch2 = - (vfs_read_retval == line_size) ? IN_PROGRESS : END_OF_FILE; + dev->_file_status_ch2 = (vfs_read_retval == line_size) ? + IN_PROGRESS : END_OF_FILE; set_fs(old_fs); filp_close(myfile, NULL); @@ -351,8 +347,8 @@ int cx25821_get_frame_ch2(struct cx25821_dev *dev, struct sram_channel *sram_ch) static void cx25821_vidups_handler_ch2(struct work_struct *work) { - struct cx25821_dev *dev = - container_of(work, struct cx25821_dev, _irq_work_entry_ch2); + struct cx25821_dev *dev = container_of(work, struct cx25821_dev, + _irq_work_entry_ch2); if (!dev) { pr_err("ERROR %s(): since container_of(work_struct) FAILED!\n", @@ -360,18 +356,16 @@ static void cx25821_vidups_handler_ch2(struct work_struct *work) return; } - cx25821_get_frame_ch2(dev, - dev->channels[dev-> - _channel2_upstream_select].sram_channels); + cx25821_get_frame_ch2(dev, dev->channels[dev-> + _channel2_upstream_select].sram_channels); } int cx25821_openfile_ch2(struct cx25821_dev *dev, struct sram_channel *sram_ch) { struct file *myfile; int i = 0, j = 0; - int line_size = - (dev->_pixel_format_ch2 == - PIXEL_FRMT_411) ? Y411_LINE_SZ : Y422_LINE_SZ; + int line_size = (dev->_pixel_format_ch2 == PIXEL_FRMT_411) ? + Y411_LINE_SZ : Y422_LINE_SZ; ssize_t vfs_read_retval = 0; char mybuf[line_size]; loff_t pos; @@ -408,8 +402,8 @@ int cx25821_openfile_ch2(struct cx25821_dev *dev, struct sram_channel *sram_ch) for (i = 0; i < dev->_lines_count_ch2; i++) { pos = offset; - vfs_read_retval = - vfs_read(myfile, mybuf, line_size, &pos); + vfs_read_retval = vfs_read(myfile, mybuf, + line_size, &pos); if (vfs_read_retval > 0 && vfs_read_retval == line_size && @@ -436,8 +430,8 @@ int cx25821_openfile_ch2(struct cx25821_dev *dev, struct sram_channel *sram_ch) break; } - dev->_file_status_ch2 = - (vfs_read_retval == line_size) ? IN_PROGRESS : END_OF_FILE; + dev->_file_status_ch2 = (vfs_read_retval == line_size) ? + IN_PROGRESS : END_OF_FILE; set_fs(old_fs); myfile->f_pos = 0; @@ -461,9 +455,8 @@ static int cx25821_upstream_buffer_prepare_ch2(struct cx25821_dev *dev, dev->_dma_phys_addr_ch2); } - dev->_dma_virt_addr_ch2 = - pci_alloc_consistent(dev->pci, dev->upstream_riscbuf_size_ch2, - &dma_addr); + dev->_dma_virt_addr_ch2 = pci_alloc_consistent(dev->pci, + dev->upstream_riscbuf_size_ch2, &dma_addr); dev->_dma_virt_start_addr_ch2 = dev->_dma_virt_addr_ch2; dev->_dma_phys_start_addr_ch2 = dma_addr; dev->_dma_phys_addr_ch2 = dma_addr; @@ -483,9 +476,8 @@ static int cx25821_upstream_buffer_prepare_ch2(struct cx25821_dev *dev, dev->_data_buf_phys_addr_ch2); } /* For Video Data buffer allocation */ - dev->_data_buf_virt_addr_ch2 = - pci_alloc_consistent(dev->pci, dev->upstream_databuf_size_ch2, - &data_dma_addr); + dev->_data_buf_virt_addr_ch2 = pci_alloc_consistent(dev->pci, + dev->upstream_databuf_size_ch2, &data_dma_addr); dev->_data_buf_phys_addr_ch2 = data_dma_addr; dev->_data_buf_size_ch2 = dev->upstream_databuf_size_ch2; @@ -687,8 +679,7 @@ int cx25821_start_video_dma_upstream_ch2(struct cx25821_dev *dev, tmp = cx_read(sram_ch->int_msk); cx_write(sram_ch->int_msk, tmp |= _intr_msk); - err = - request_irq(dev->pci->irq, cx25821_upstream_irq_ch2, + err = request_irq(dev->pci->irq, cx25821_upstream_irq_ch2, IRQF_SHARED, dev->name, dev); if (err < 0) { pr_err("%s: can't get upstream IRQ %d\n", @@ -748,12 +739,11 @@ int cx25821_vidupstream_init_ch2(struct cx25821_dev *dev, int channel_select, dev->_file_status_ch2 = RESET_STATUS; dev->_lines_count_ch2 = dev->_isNTSC_ch2 ? 480 : 576; dev->_pixel_format_ch2 = pixel_format; - dev->_line_size_ch2 = - (dev->_pixel_format_ch2 == - PIXEL_FRMT_422) ? (WIDTH_D1 * 2) : (WIDTH_D1 * 3) / 2; + dev->_line_size_ch2 = (dev->_pixel_format_ch2 == PIXEL_FRMT_422) ? + (WIDTH_D1 * 2) : (WIDTH_D1 * 3) / 2; data_frame_size = dev->_isNTSC_ch2 ? NTSC_DATA_BUF_SZ : PAL_DATA_BUF_SZ; - risc_buffer_size = - dev->_isNTSC_ch2 ? NTSC_RISC_BUF_SIZE : PAL_RISC_BUF_SIZE; + risc_buffer_size = dev->_isNTSC_ch2 ? + NTSC_RISC_BUF_SIZE : PAL_RISC_BUF_SIZE; if (dev->input_filename_ch2) { str_length = strlen(dev->input_filename_ch2); @@ -778,15 +768,13 @@ int cx25821_vidupstream_init_ch2(struct cx25821_dev *dev, int channel_select, /* Default if filename is empty string */ if (strcmp(dev->input_filename_ch2, "") == 0) { if (dev->_isNTSC_ch2) { - dev->_filename_ch2 = - (dev->_pixel_format_ch2 == - PIXEL_FRMT_411) ? "/root/vid411.yuv" : - "/root/vidtest.yuv"; + dev->_filename_ch2 = (dev->_pixel_format_ch2 == + PIXEL_FRMT_411) ? "/root/vid411.yuv" : + "/root/vidtest.yuv"; } else { - dev->_filename_ch2 = - (dev->_pixel_format_ch2 == - PIXEL_FRMT_411) ? "/root/pal411.yuv" : - "/root/pal422.yuv"; + dev->_filename_ch2 = (dev->_pixel_format_ch2 == + PIXEL_FRMT_411) ? "/root/pal411.yuv" : + "/root/pal422.yuv"; } } -- cgit v0.10.2 From 16f0fda705371d880d79c0bd44fc301a45a1deb7 Mon Sep 17 00:00:00 2001 From: "Leonid V. Fedorenchik" Date: Sat, 22 Oct 2011 01:43:46 -0300 Subject: [media] cx25821-video-upstream.c: Remove braces Delete curly braces around single if-else statements. Signed-off-by: Leonid V. Fedorenchik Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/cx25821/cx25821-video-upstream.c b/drivers/media/video/cx25821/cx25821-video-upstream.c index c0b8006..61b5397 100644 --- a/drivers/media/video/cx25821/cx25821-video-upstream.c +++ b/drivers/media/video/cx25821/cx25821-video-upstream.c @@ -326,16 +326,12 @@ int cx25821_get_frame(struct cx25821_dev *dev, struct sram_channel *sram_ch) if (dev->_file_status == END_OF_FILE) return 0; - if (dev->_isNTSC) { - frame_size = - (line_size == - Y411_LINE_SZ) ? FRAME_SIZE_NTSC_Y411 : - FRAME_SIZE_NTSC_Y422; - } else { - frame_size = - (line_size == - Y411_LINE_SZ) ? FRAME_SIZE_PAL_Y411 : FRAME_SIZE_PAL_Y422; - } + if (dev->_isNTSC) + frame_size = (line_size == Y411_LINE_SZ) ? + FRAME_SIZE_NTSC_Y411 : FRAME_SIZE_NTSC_Y422; + else + frame_size = (line_size == Y411_LINE_SZ) ? + FRAME_SIZE_PAL_Y411 : FRAME_SIZE_PAL_Y422; frame_offset = (frame_index_temp > 0) ? frame_size : 0; file_offset = dev->_frame_count * frame_size; @@ -507,10 +503,9 @@ int cx25821_upstream_buffer_prepare(struct cx25821_dev *dev, dma_addr_t dma_addr; dma_addr_t data_dma_addr; - if (dev->_dma_virt_addr != NULL) { + if (dev->_dma_virt_addr != NULL) pci_free_consistent(dev->pci, dev->upstream_riscbuf_size, - dev->_dma_virt_addr, dev->_dma_phys_addr); - } + dev->_dma_virt_addr, dev->_dma_phys_addr); dev->_dma_virt_addr = pci_alloc_consistent(dev->pci, dev->upstream_riscbuf_size, @@ -528,11 +523,10 @@ int cx25821_upstream_buffer_prepare(struct cx25821_dev *dev, /* Clear memory at address */ memset(dev->_dma_virt_addr, 0, dev->_risc_size); - if (dev->_data_buf_virt_addr != NULL) { + if (dev->_data_buf_virt_addr != NULL) pci_free_consistent(dev->pci, dev->upstream_databuf_size, - dev->_data_buf_virt_addr, - dev->_data_buf_phys_addr); - } + dev->_data_buf_virt_addr, + dev->_data_buf_phys_addr); /* For Video Data buffer allocation */ dev->_data_buf_virt_addr = pci_alloc_consistent(dev->pci, dev->upstream_databuf_size, @@ -672,10 +666,9 @@ static irqreturn_t cx25821_upstream_irq(int irq, void *dev_id) vid_status = cx_read(sram_ch->int_stat); /* Only deal with our interrupt */ - if (vid_status) { - handled = - cx25821_video_upstream_irq(dev, channel_num, vid_status); - } + if (vid_status) + handled = cx25821_video_upstream_irq(dev, channel_num, + vid_status); if (handled < 0) cx25821_stop_upstream_video_ch1(dev); -- cgit v0.10.2 From 2c68e933a9ff2e51c319aee7e841c89ab833bc8a Mon Sep 17 00:00:00 2001 From: "Leonid V. Fedorenchik" Date: Sat, 22 Oct 2011 01:43:47 -0300 Subject: [media] cx25821-video-upstream.c: Fix indent Change indent of statements to use tabs and to improve readability. Signed-off-by: Leonid V. Fedorenchik Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/cx25821/cx25821-video-upstream.c b/drivers/media/video/cx25821/cx25821-video-upstream.c index 61b5397..0259a40 100644 --- a/drivers/media/video/cx25821/cx25821-video-upstream.c +++ b/drivers/media/video/cx25821/cx25821-video-upstream.c @@ -136,7 +136,7 @@ static __le32 *cx25821_risc_field_upstream(struct cx25821_dev *dev, __le32 * rp, { unsigned int line, i; struct sram_channel *sram_ch = - dev->channels[dev->_channel_upstream_select].sram_channels; + dev->channels[dev->_channel_upstream_select].sram_channels; int dist_betwn_starts = bpl * 2; /* sync instruction */ @@ -214,13 +214,9 @@ int cx25821_risc_buffer_upstream(struct cx25821_dev *dev, if (UNSET != top_offset) { fifo_enable = (frame == 0) ? FIFO_ENABLE : FIFO_DISABLE; rp = cx25821_risc_field_upstream(dev, rp, - dev-> - _data_buf_phys_addr + - databuf_offset, - top_offset, 0, bpl, - odd_num_lines, - fifo_enable, - ODD_FIELD); + dev->_data_buf_phys_addr + + databuf_offset, top_offset, 0, bpl, + odd_num_lines, fifo_enable, ODD_FIELD); } fifo_enable = FIFO_DISABLE; @@ -255,7 +251,7 @@ int cx25821_risc_buffer_upstream(struct cx25821_dev *dev, void cx25821_stop_upstream_video_ch1(struct cx25821_dev *dev) { struct sram_channel *sram_ch = - dev->channels[VID_UPSTREAM_SRAM_CHANNEL_I].sram_channels; + dev->channels[VID_UPSTREAM_SRAM_CHANNEL_I].sram_channels; u32 tmp = 0; if (!dev->_is_running) { @@ -829,14 +825,12 @@ int cx25821_vidupstream_init_ch1(struct cx25821_dev *dev, int channel_select, if (strcmp(dev->input_filename, "") == 0) { if (dev->_isNTSC) { dev->_filename = - (dev->_pixel_format == - PIXEL_FRMT_411) ? "/root/vid411.yuv" : - "/root/vidtest.yuv"; + (dev->_pixel_format == PIXEL_FRMT_411) ? + "/root/vid411.yuv" : "/root/vidtest.yuv"; } else { dev->_filename = - (dev->_pixel_format == - PIXEL_FRMT_411) ? "/root/pal411.yuv" : - "/root/pal422.yuv"; + (dev->_pixel_format == PIXEL_FRMT_411) ? + "/root/pal411.yuv" : "/root/pal422.yuv"; } } -- cgit v0.10.2 From 8eb1fdfff0c939f3f5c6b48a6e54996e7ac0ad91 Mon Sep 17 00:00:00 2001 From: "Leonid V. Fedorenchik" Date: Sat, 22 Oct 2011 01:43:48 -0300 Subject: [media] cx25821-video-upstream.c: Change line endings Change obscure line endings to less obscure ones. (improve readability) Signed-off-by: Leonid V. Fedorenchik Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/cx25821/cx25821-video-upstream.c b/drivers/media/video/cx25821/cx25821-video-upstream.c index 0259a40..1032263 100644 --- a/drivers/media/video/cx25821/cx25821-video-upstream.c +++ b/drivers/media/video/cx25821/cx25821-video-upstream.c @@ -194,15 +194,12 @@ int cx25821_risc_buffer_upstream(struct cx25821_dev *dev, if (dev->_isNTSC) { odd_num_lines = singlefield_lines + 1; risc_program_size = FRAME1_VID_PROG_SIZE; - frame_size = - (bpl == - Y411_LINE_SZ) ? FRAME_SIZE_NTSC_Y411 : - FRAME_SIZE_NTSC_Y422; + frame_size = (bpl == Y411_LINE_SZ) ? + FRAME_SIZE_NTSC_Y411 : FRAME_SIZE_NTSC_Y422; } else { risc_program_size = PAL_VID_PROG_SIZE; - frame_size = - (bpl == - Y411_LINE_SZ) ? FRAME_SIZE_PAL_Y411 : FRAME_SIZE_PAL_Y422; + frame_size = (bpl == Y411_LINE_SZ) ? + FRAME_SIZE_PAL_Y411 : FRAME_SIZE_PAL_Y422; } /* Virtual address of Risc buffer program */ @@ -230,8 +227,8 @@ int cx25821_risc_buffer_upstream(struct cx25821_dev *dev, if (frame == 0) { risc_flag = RISC_CNT_RESET; - risc_phys_jump_addr = - dev->_dma_phys_start_addr + risc_program_size; + risc_phys_jump_addr = dev->_dma_phys_start_addr + + risc_program_size; } else { risc_phys_jump_addr = dev->_dma_phys_start_addr; risc_flag = RISC_CNT_INC; @@ -308,9 +305,8 @@ int cx25821_get_frame(struct cx25821_dev *dev, struct sram_channel *sram_ch) struct file *myfile; int frame_index_temp = dev->_frame_index; int i = 0; - int line_size = - (dev->_pixel_format == - PIXEL_FRMT_411) ? Y411_LINE_SZ : Y422_LINE_SZ; + int line_size = (dev->_pixel_format == PIXEL_FRMT_411) ? + Y411_LINE_SZ : Y422_LINE_SZ; int frame_size = 0; int frame_offset = 0; ssize_t vfs_read_retval = 0; @@ -361,8 +357,8 @@ int cx25821_get_frame(struct cx25821_dev *dev, struct sram_channel *sram_ch) for (i = 0; i < dev->_lines_count; i++) { pos = file_offset; - vfs_read_retval = - vfs_read(myfile, mybuf, line_size, &pos); + vfs_read_retval = vfs_read(myfile, mybuf, line_size, + &pos); if (vfs_read_retval > 0 && vfs_read_retval == line_size && dev->_data_buf_virt_addr != NULL) { @@ -384,8 +380,8 @@ int cx25821_get_frame(struct cx25821_dev *dev, struct sram_channel *sram_ch) if (i > 0) dev->_frame_count++; - dev->_file_status = - (vfs_read_retval == line_size) ? IN_PROGRESS : END_OF_FILE; + dev->_file_status = (vfs_read_retval == line_size) ? + IN_PROGRESS : END_OF_FILE; set_fs(old_fs); filp_close(myfile, NULL); @@ -396,8 +392,8 @@ int cx25821_get_frame(struct cx25821_dev *dev, struct sram_channel *sram_ch) static void cx25821_vidups_handler(struct work_struct *work) { - struct cx25821_dev *dev = - container_of(work, struct cx25821_dev, _irq_work_entry); + struct cx25821_dev *dev = container_of(work, struct cx25821_dev, + _irq_work_entry); if (!dev) { pr_err("ERROR %s(): since container_of(work_struct) FAILED!\n", @@ -405,18 +401,16 @@ static void cx25821_vidups_handler(struct work_struct *work) return; } - cx25821_get_frame(dev, - dev->channels[dev->_channel_upstream_select]. - sram_channels); + cx25821_get_frame(dev, dev->channels[dev->_channel_upstream_select]. + sram_channels); } int cx25821_openfile(struct cx25821_dev *dev, struct sram_channel *sram_ch) { struct file *myfile; int i = 0, j = 0; - int line_size = - (dev->_pixel_format == - PIXEL_FRMT_411) ? Y411_LINE_SZ : Y422_LINE_SZ; + int line_size = (dev->_pixel_format == PIXEL_FRMT_411) ? + Y411_LINE_SZ : Y422_LINE_SZ; ssize_t vfs_read_retval = 0; char mybuf[line_size]; loff_t pos; @@ -453,8 +447,8 @@ int cx25821_openfile(struct cx25821_dev *dev, struct sram_channel *sram_ch) for (i = 0; i < dev->_lines_count; i++) { pos = offset; - vfs_read_retval = - vfs_read(myfile, mybuf, line_size, &pos); + vfs_read_retval = vfs_read(myfile, mybuf, + line_size, &pos); if (vfs_read_retval > 0 && vfs_read_retval == line_size @@ -481,8 +475,8 @@ int cx25821_openfile(struct cx25821_dev *dev, struct sram_channel *sram_ch) break; } - dev->_file_status = - (vfs_read_retval == line_size) ? IN_PROGRESS : END_OF_FILE; + dev->_file_status = (vfs_read_retval == line_size) ? + IN_PROGRESS : END_OF_FILE; set_fs(old_fs); myfile->f_pos = 0; @@ -503,9 +497,8 @@ int cx25821_upstream_buffer_prepare(struct cx25821_dev *dev, pci_free_consistent(dev->pci, dev->upstream_riscbuf_size, dev->_dma_virt_addr, dev->_dma_phys_addr); - dev->_dma_virt_addr = - pci_alloc_consistent(dev->pci, dev->upstream_riscbuf_size, - &dma_addr); + dev->_dma_virt_addr = pci_alloc_consistent(dev->pci, + dev->upstream_riscbuf_size, &dma_addr); dev->_dma_virt_start_addr = dev->_dma_virt_addr; dev->_dma_phys_start_addr = dma_addr; dev->_dma_phys_addr = dma_addr; @@ -524,9 +517,8 @@ int cx25821_upstream_buffer_prepare(struct cx25821_dev *dev, dev->_data_buf_virt_addr, dev->_data_buf_phys_addr); /* For Video Data buffer allocation */ - dev->_data_buf_virt_addr = - pci_alloc_consistent(dev->pci, dev->upstream_databuf_size, - &data_dma_addr); + dev->_data_buf_virt_addr = pci_alloc_consistent(dev->pci, + dev->upstream_databuf_size, &data_dma_addr); dev->_data_buf_phys_addr = data_dma_addr; dev->_data_buf_size = dev->upstream_databuf_size; @@ -543,9 +535,8 @@ int cx25821_upstream_buffer_prepare(struct cx25821_dev *dev, return ret; /* Create RISC programs */ - ret = - cx25821_risc_buffer_upstream(dev, dev->pci, 0, bpl, - dev->_lines_count); + ret = cx25821_risc_buffer_upstream(dev, dev->pci, 0, bpl, + dev->_lines_count); if (ret < 0) { pr_info("Failed creating Video Upstream Risc programs!\n"); goto error; @@ -736,8 +727,7 @@ int cx25821_start_video_dma_upstream(struct cx25821_dev *dev, tmp = cx_read(sram_ch->int_msk); cx_write(sram_ch->int_msk, tmp |= _intr_msk); - err = - request_irq(dev->pci->irq, cx25821_upstream_irq, + err = request_irq(dev->pci->irq, cx25821_upstream_irq, IRQF_SHARED, dev->name, dev); if (err < 0) { pr_err("%s: can't get upstream IRQ %d\n", @@ -796,12 +786,11 @@ int cx25821_vidupstream_init_ch1(struct cx25821_dev *dev, int channel_select, dev->_file_status = RESET_STATUS; dev->_lines_count = dev->_isNTSC ? 480 : 576; dev->_pixel_format = pixel_format; - dev->_line_size = - (dev->_pixel_format == - PIXEL_FRMT_422) ? (WIDTH_D1 * 2) : (WIDTH_D1 * 3) / 2; + dev->_line_size = (dev->_pixel_format == PIXEL_FRMT_422) ? + (WIDTH_D1 * 2) : (WIDTH_D1 * 3) / 2; data_frame_size = dev->_isNTSC ? NTSC_DATA_BUF_SZ : PAL_DATA_BUF_SZ; - risc_buffer_size = - dev->_isNTSC ? NTSC_RISC_BUF_SIZE : PAL_RISC_BUF_SIZE; + risc_buffer_size = dev->_isNTSC ? + NTSC_RISC_BUF_SIZE : PAL_RISC_BUF_SIZE; if (dev->input_filename) { str_length = strlen(dev->input_filename); @@ -839,13 +828,11 @@ int cx25821_vidupstream_init_ch1(struct cx25821_dev *dev, int channel_select, dev->_file_status = RESET_STATUS; dev->_lines_count = dev->_isNTSC ? 480 : 576; dev->_pixel_format = pixel_format; - dev->_line_size = - (dev->_pixel_format == - PIXEL_FRMT_422) ? (WIDTH_D1 * 2) : (WIDTH_D1 * 3) / 2; + dev->_line_size = (dev->_pixel_format == PIXEL_FRMT_422) ? + (WIDTH_D1 * 2) : (WIDTH_D1 * 3) / 2; - retval = - cx25821_sram_channel_setup_upstream(dev, sram_ch, dev->_line_size, - 0); + retval = cx25821_sram_channel_setup_upstream(dev, sram_ch, + dev->_line_size, 0); /* setup fifo + format */ cx25821_set_pixelengine(dev, sram_ch, dev->_pixel_format); -- cgit v0.10.2 From 7e7beb8c255e91bfb4701f2757036c8fbe5a6592 Mon Sep 17 00:00:00 2001 From: "Leonid V. Fedorenchik" Date: Sat, 22 Oct 2011 01:43:49 -0300 Subject: [media] cx25821-video.c: Delete empty line Delete unnecessary empty line. Signed-off-by: Leonid V. Fedorenchik Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/cx25821/cx25821-video.c b/drivers/media/video/cx25821/cx25821-video.c index 4d6907c..79c4553 100644 --- a/drivers/media/video/cx25821/cx25821-video.c +++ b/drivers/media/video/cx25821/cx25821-video.c @@ -528,7 +528,6 @@ int cx25821_video_register(struct cx25821_dev *dev) #endif mutex_unlock(&dev->lock); - return 0; fail_unreg: -- cgit v0.10.2 From 1316b63ccde5bed161c6e346cc8f1752bd5c83cc Mon Sep 17 00:00:00 2001 From: "Leonid V. Fedorenchik" Date: Sat, 22 Oct 2011 01:43:50 -0300 Subject: [media] cx25821-video.c: Change spaces Change double spaces between lexemes into single spaces. Signed-off-by: Leonid V. Fedorenchik Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/cx25821/cx25821-video.c b/drivers/media/video/cx25821/cx25821-video.c index 79c4553..df4f5b1 100644 --- a/drivers/media/video/cx25821/cx25821-video.c +++ b/drivers/media/video/cx25821/cx25821-video.c @@ -1931,9 +1931,9 @@ static long video_ioctl_set(struct file *file, unsigned int cmd, static long cx25821_video_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { - int ret = 0; + int ret = 0; - struct cx25821_fh *fh = file->private_data; + struct cx25821_fh *fh = file->private_data; /* check to see if it's the video upstream */ if (fh->channel_id == SRAM_CH09) { -- cgit v0.10.2 From a1937e191906c612e5675e52dd86c5a4b1d44a81 Mon Sep 17 00:00:00 2001 From: "Leonid V. Fedorenchik" Date: Sat, 22 Oct 2011 01:43:51 -0300 Subject: [media] cx25821-video.c: Fix assignment Change double assignment in one statement into two assignment statements. Signed-off-by: Leonid V. Fedorenchik Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/cx25821/cx25821-video.c b/drivers/media/video/cx25821/cx25821-video.c index df4f5b1..4cca7ee 100644 --- a/drivers/media/video/cx25821/cx25821-video.c +++ b/drivers/media/video/cx25821/cx25821-video.c @@ -1622,7 +1622,8 @@ int cx25821_vidioc_cropcap(struct file *file, void *priv, if (cropcap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) return -EINVAL; - cropcap->bounds.top = cropcap->bounds.left = 0; + cropcap->bounds.top = 0; + cropcap->bounds.left = 0; cropcap->bounds.width = 720; cropcap->bounds.height = dev->tvnorm == V4L2_STD_PAL_BG ? 576 : 480; cropcap->pixelaspect.numerator = -- cgit v0.10.2 From 4a33b6f8bdf3b5a17737f66eef79b595cf3541a3 Mon Sep 17 00:00:00 2001 From: "Leonid V. Fedorenchik" Date: Sat, 22 Oct 2011 01:43:52 -0300 Subject: [media] cx25821-video.c: Fix definitions Change multiple definitions in one statement into multiple statements with one definition per statement. Signed-off-by: Leonid V. Fedorenchik Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/cx25821/cx25821-video.c b/drivers/media/video/cx25821/cx25821-video.c index 4cca7ee..278e06b 100644 --- a/drivers/media/video/cx25821/cx25821-video.c +++ b/drivers/media/video/cx25821/cx25821-video.c @@ -1829,8 +1829,11 @@ static long video_ioctl_set(struct file *file, unsigned int cmd, struct downstream_user_struct *data_from_user; int command; int width = 720; - int selected_channel = 0, pix_format = 0, i = 0; - int cif_enable = 0, cif_width = 0; + int selected_channel = 0; + int pix_format = 0; + int i = 0; + int cif_enable = 0; + int cif_width = 0; u32 value = 0; data_from_user = (struct downstream_user_struct *)arg; -- cgit v0.10.2 From cd52b2cf9bd60b1887e2ade2a2e12f155240fa9d Mon Sep 17 00:00:00 2001 From: "Leonid V. Fedorenchik" Date: Sat, 22 Oct 2011 01:43:53 -0300 Subject: [media] cx25821-video.c: Move operators Move operator in complex expression to the end of the line to preserve consistency. Signed-off-by: Leonid V. Fedorenchik Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/cx25821/cx25821-video.c b/drivers/media/video/cx25821/cx25821-video.c index 278e06b..4bd7d71 100644 --- a/drivers/media/video/cx25821/cx25821-video.c +++ b/drivers/media/video/cx25821/cx25821-video.c @@ -616,8 +616,8 @@ int cx25821_buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb, if (channel_opened >= 0 && channel_opened <= 7) { if (dev->channels[channel_opened] .use_cif_resolution) { - if (dev->tvnorm & V4L2_STD_PAL_BG - || dev->tvnorm & V4L2_STD_PAL_DK) + if (dev->tvnorm & V4L2_STD_PAL_BG || + dev->tvnorm & V4L2_STD_PAL_DK) bpl_local = 352 << 1; else bpl_local = -- cgit v0.10.2 From f253981406c9f9f79d6439fc2bd31fd1a10f68cb Mon Sep 17 00:00:00 2001 From: "Leonid V. Fedorenchik" Date: Sat, 22 Oct 2011 01:43:54 -0300 Subject: [media] cx25821-video.c: Fix indent Fix indent of statements to improve readability. Signed-off-by: Leonid V. Fedorenchik Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/cx25821/cx25821-video.c b/drivers/media/video/cx25821/cx25821-video.c index 4bd7d71..fce203c 100644 --- a/drivers/media/video/cx25821/cx25821-video.c +++ b/drivers/media/video/cx25821/cx25821-video.c @@ -118,12 +118,12 @@ void cx25821_dump_video_queue(struct cx25821_dev *dev, if (!list_empty(&q->active)) { list_for_each(item, &q->active) - buf = list_entry(item, struct cx25821_buffer, vb.queue); + buf = list_entry(item, struct cx25821_buffer, vb.queue); } if (!list_empty(&q->queued)) { list_for_each(item, &q->queued) - buf = list_entry(item, struct cx25821_buffer, vb.queue); + buf = list_entry(item, struct cx25821_buffer, vb.queue); } } @@ -484,8 +484,7 @@ int cx25821_video_register(struct cx25821_dev *dev) cx25821_init_controls(dev, i); cx25821_risc_stopper(dev->pci, &dev->channels[i].vidq.stopper, - dev->channels[i].sram_channels->dma_ctl, - 0x11, 0); + dev->channels[i].sram_channels->dma_ctl, 0x11, 0); dev->channels[i].sram_channels = &cx25821_sram_channels[i]; dev->channels[i].video_dev = NULL; @@ -557,7 +556,7 @@ int cx25821_buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb, struct cx25821_fh *fh = q->priv_data; struct cx25821_dev *dev = fh->dev; struct cx25821_buffer *buf = - container_of(vb, struct cx25821_buffer, vb); + container_of(vb, struct cx25821_buffer, vb); int rc, init_buffer = 0; u32 line0_offset, line1_offset; struct videobuf_dmabuf *dma = videobuf_to_dma(&buf->vb); @@ -684,7 +683,7 @@ void cx25821_buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb) { struct cx25821_buffer *buf = - container_of(vb, struct cx25821_buffer, vb); + container_of(vb, struct cx25821_buffer, vb); cx25821_free_buffer(q, buf); } @@ -722,7 +721,7 @@ int cx25821_video_mmap(struct file *file, struct vm_area_struct *vma) static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb) { struct cx25821_buffer *buf = - container_of(vb, struct cx25821_buffer, vb); + container_of(vb, struct cx25821_buffer, vb); struct cx25821_buffer *prev; struct cx25821_fh *fh = vq->priv_data; struct cx25821_dev *dev = fh->dev; @@ -813,7 +812,7 @@ static int video_open(struct file *file) for (i = 0; i < MAX_VID_CHANNEL_NUM; i++) { if (h->channels[i].video_dev && - h->channels[i].video_dev->minor == minor) { + h->channels[i].video_dev->minor == minor) { dev = h; ch_id = i; type = V4L2_BUF_TYPE_VIDEO_CAPTURE; @@ -1453,38 +1452,38 @@ static const struct v4l2_queryctrl no_ctl = { static struct v4l2_queryctrl cx25821_ctls[] = { /* --- video --- */ { - .id = V4L2_CID_BRIGHTNESS, - .name = "Brightness", - .minimum = 0, - .maximum = 10000, - .step = 1, - .default_value = 6200, - .type = V4L2_CTRL_TYPE_INTEGER, - }, { - .id = V4L2_CID_CONTRAST, - .name = "Contrast", - .minimum = 0, - .maximum = 10000, - .step = 1, - .default_value = 5000, - .type = V4L2_CTRL_TYPE_INTEGER, - }, { - .id = V4L2_CID_SATURATION, - .name = "Saturation", - .minimum = 0, - .maximum = 10000, - .step = 1, - .default_value = 5000, - .type = V4L2_CTRL_TYPE_INTEGER, - }, { - .id = V4L2_CID_HUE, - .name = "Hue", - .minimum = 0, - .maximum = 10000, - .step = 1, - .default_value = 5000, - .type = V4L2_CTRL_TYPE_INTEGER, - } + .id = V4L2_CID_BRIGHTNESS, + .name = "Brightness", + .minimum = 0, + .maximum = 10000, + .step = 1, + .default_value = 6200, + .type = V4L2_CTRL_TYPE_INTEGER, + }, { + .id = V4L2_CID_CONTRAST, + .name = "Contrast", + .minimum = 0, + .maximum = 10000, + .step = 1, + .default_value = 5000, + .type = V4L2_CTRL_TYPE_INTEGER, + }, { + .id = V4L2_CID_SATURATION, + .name = "Saturation", + .minimum = 0, + .maximum = 10000, + .step = 1, + .default_value = 5000, + .type = V4L2_CTRL_TYPE_INTEGER, + }, { + .id = V4L2_CID_HUE, + .name = "Hue", + .minimum = 0, + .maximum = 10000, + .step = 1, + .default_value = 5000, + .type = V4L2_CTRL_TYPE_INTEGER, + } }; static const int CX25821_CTLS = ARRAY_SIZE(cx25821_ctls); -- cgit v0.10.2 From 0abfefbe497d8d2a173f70aa3beac89a01fc1f51 Mon Sep 17 00:00:00 2001 From: "Leonid V. Fedorenchik" Date: Sat, 22 Oct 2011 01:43:55 -0300 Subject: [media] cx25821-video.c: Change line endings Change obscure line endings to less obscure ones. (improve readability) Signed-off-by: Leonid V. Fedorenchik Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/cx25821/cx25821-video.c b/drivers/media/video/cx25821/cx25821-video.c index fce203c..ffd8bc7 100644 --- a/drivers/media/video/cx25821/cx25821-video.c +++ b/drivers/media/video/cx25821/cx25821-video.c @@ -140,8 +140,8 @@ void cx25821_video_wakeup(struct cx25821_dev *dev, struct cx25821_dmaqueue *q, break; } - buf = - list_entry(q->active.next, struct cx25821_buffer, vb.queue); + buf = list_entry(q->active.next, struct cx25821_buffer, + vb.queue); /* count comes from the hw and it is 16bit wide -- * this trick handles wrap-arounds correctly for @@ -318,8 +318,8 @@ int cx25821_restart_video_queue(struct cx25821_dev *dev, struct list_head *item; if (!list_empty(&q->active)) { - buf = - list_entry(q->active.next, struct cx25821_buffer, vb.queue); + buf = list_entry(q->active.next, struct cx25821_buffer, + vb.queue); cx25821_start_video_dma(dev, q, buf, channel); @@ -337,8 +337,8 @@ int cx25821_restart_video_queue(struct cx25821_dev *dev, if (list_empty(&q->queued)) return 0; - buf = - list_entry(q->queued.next, struct cx25821_buffer, vb.queue); + buf = list_entry(q->queued.next, struct cx25821_buffer, + vb.queue); if (NULL == prev) { list_move_tail(&buf->vb.queue, &q->active); @@ -375,8 +375,8 @@ void cx25821_vid_timeout(unsigned long data) spin_lock_irqsave(&dev->slock, flags); while (!list_empty(&q->active)) { - buf = - list_entry(q->active.next, struct cx25821_buffer, vb.queue); + buf = list_entry(q->active.next, struct cx25821_buffer, + vb.queue); list_del(&buf->vb.queue); buf->vb.state = VIDEOBUF_ERROR; @@ -498,15 +498,14 @@ int cx25821_video_register(struct cx25821_dev *dev) dev->channels[i].timeout_data.dev = dev; dev->channels[i].timeout_data.channel = &cx25821_sram_channels[i]; - dev->channels[i].vidq.timeout.function = - cx25821_vid_timeout; + dev->channels[i].vidq.timeout.function = cx25821_vid_timeout; dev->channels[i].vidq.timeout.data = (unsigned long)&dev->channels[i].timeout_data; init_timer(&dev->channels[i].vidq.timeout); /* register v4l devices */ - dev->channels[i].video_dev = cx25821_vdev_init(dev, - dev->pci, &cx25821_video_device, "video"); + dev->channels[i].video_dev = cx25821_vdev_init(dev, dev->pci, + &cx25821_video_device, "video"); err = video_register_device(dev->channels[i].video_dev, VFL_TYPE_GRABBER, video_nr[dev->nr]); @@ -619,10 +618,9 @@ int cx25821_buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb, dev->tvnorm & V4L2_STD_PAL_DK) bpl_local = 352 << 1; else - bpl_local = - dev->channels[channel_opened]. - cif_width << - 1; + bpl_local = dev->channels[ + channel_opened]. + cif_width << 1; } } } @@ -846,11 +844,10 @@ static int video_open(struct file *file) v4l2_prio_open(&dev->channels[ch_id].prio, &fh->prio); - videobuf_queue_sg_init(&fh->vidq, &cx25821_video_qops, - &dev->pci->dev, &dev->slock, - V4L2_BUF_TYPE_VIDEO_CAPTURE, - V4L2_FIELD_INTERLACED, - sizeof(struct cx25821_buffer), fh, NULL); + videobuf_queue_sg_init(&fh->vidq, &cx25821_video_qops, &dev->pci->dev, + &dev->slock, V4L2_BUF_TYPE_VIDEO_CAPTURE, + V4L2_FIELD_INTERLACED, sizeof(struct cx25821_buffer), + fh, NULL); dprintk(1, "post videobuf_queue_init()\n"); mutex_unlock(&cx25821_devlist_mutex); @@ -1166,8 +1163,8 @@ int cx25821_vidioc_querycap(struct file *file, void *priv, strlcpy(cap->card, cx25821_boards[dev->board].name, sizeof(cap->card)); sprintf(cap->bus_info, "PCIe:%s", pci_name(dev->pci)); cap->version = CX25821_VERSION_CODE; - cap->capabilities = - V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE | V4L2_CAP_STREAMING; + cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE | + V4L2_CAP_STREAMING; if (UNSET != dev->tuner_type) cap->capabilities |= V4L2_CAP_TUNER; return 0; @@ -1897,8 +1894,8 @@ static long video_ioctl_set(struct file *file, unsigned int cmd, } if (selected_channel <= 7 && selected_channel >= 0) { - dev->channels[selected_channel]. - use_cif_resolution = cif_enable; + dev->channels[selected_channel].use_cif_resolution = + cif_enable; dev->channels[selected_channel].cif_width = width; } else { for (i = 0; i < VID_CHANNEL_NUM; i++) { -- cgit v0.10.2 From c7855ee531efa77d3837e22a0354d20f64d67446 Mon Sep 17 00:00:00 2001 From: "Leonid V. Fedorenchik" Date: Sat, 22 Oct 2011 01:43:56 -0300 Subject: [media] cx25821.h: Line up defines Line up constant defines to the same column. Signed-off-by: Leonid V. Fedorenchik Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/cx25821/cx25821.h b/drivers/media/video/cx25821/cx25821.h index 2d2d009..b9aa801 100644 --- a/drivers/media/video/cx25821/cx25821.h +++ b/drivers/media/video/cx25821/cx25821.h @@ -67,7 +67,7 @@ #define MAX_CAMERAS 16 /* Max number of inputs by card */ -#define MAX_CX25821_INPUT 8 +#define MAX_CX25821_INPUT 8 #define INPUT(nr) (&cx25821_boards[dev->board].input[nr]) #define RESOURCE_VIDEO0 1 #define RESOURCE_VIDEO1 2 @@ -85,7 +85,7 @@ #define BUFFER_TIMEOUT (HZ) /* 0.5 seconds */ -#define UNKNOWN_BOARD 0 +#define UNKNOWN_BOARD 0 #define CX25821_BOARD 1 /* Currently supported by the driver */ -- cgit v0.10.2 From 98680557f3ce7eadae0ceda4484fd6c7a13ba3be Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Wed, 9 Nov 2011 08:26:32 -0300 Subject: [media] easycap: cleanup function usage 1. Remove declarations of none global functions from easycap.h and make them static in the c-files. 2. Reorder static functions to reduce number of forward declarations. 3. Remove unused functions. Signed-off-by: Tomas Winkler Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/staging/media/easycap/easycap.h b/drivers/staging/media/easycap/easycap.h index 7b256a9..899e572 100644 --- a/drivers/staging/media/easycap/easycap.h +++ b/drivers/staging/media/easycap/easycap.h @@ -470,71 +470,49 @@ struct easycap { */ /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ long easycap_unlocked_ioctl(struct file *, unsigned int, unsigned long); -int easycap_dqbuf(struct easycap *, int); -int submit_video_urbs(struct easycap *); -int kill_video_urbs(struct easycap *); -int field2frame(struct easycap *); -int redaub(struct easycap *, void *, void *, - int, int, u8, u8, bool); -void easycap_testcard(struct easycap *, int); -int fillin_formats(void); -int newinput(struct easycap *, int); -int adjust_standard(struct easycap *, v4l2_std_id); -int adjust_format(struct easycap *, u32, u32, u32, - int, bool); -int adjust_brightness(struct easycap *, int); -int adjust_contrast(struct easycap *, int); -int adjust_saturation(struct easycap *, int); -int adjust_hue(struct easycap *, int); -int adjust_volume(struct easycap *, int); +int easycap_dqbuf(struct easycap *, int); +int submit_video_urbs(struct easycap *); +int kill_video_urbs(struct easycap *); +void easycap_testcard(struct easycap *, int); +int fillin_formats(void); +int newinput(struct easycap *, int); + +int adjust_standard(struct easycap *, v4l2_std_id); +int adjust_format(struct easycap *, u32, u32, u32, int, bool); +int adjust_brightness(struct easycap *, int); +int adjust_contrast(struct easycap *, int); +int adjust_saturation(struct easycap *, int); +int adjust_hue(struct easycap *, int); /*---------------------------------------------------------------------------*/ /* * AUDIO FUNCTION PROTOTYPES */ /*---------------------------------------------------------------------------*/ -int easycap_alsa_probe(struct easycap *); -void easycap_alsa_complete(struct urb *); - -int easycap_sound_setup(struct easycap *); -int submit_audio_urbs(struct easycap *); -int kill_audio_urbs(struct easycap *); -void easyoss_testtone(struct easycap *, int); -int audio_setup(struct easycap *); +int easycap_alsa_probe(struct easycap *); +void easycap_alsa_complete(struct urb *); +int audio_setup(struct easycap *); /*---------------------------------------------------------------------------*/ /* * LOW-LEVEL FUNCTION PROTOTYPES */ /*---------------------------------------------------------------------------*/ -int audio_gainget(struct usb_device *); -int audio_gainset(struct usb_device *, s8); - -int set_interface(struct usb_device *, u16); -int wakeup_device(struct usb_device *); -int confirm_resolution(struct usb_device *); -int confirm_stream(struct usb_device *); - -int setup_stk(struct usb_device *, bool); -int setup_saa(struct usb_device *, bool); -int setup_vt(struct usb_device *); -int check_stk(struct usb_device *, bool); -int check_saa(struct usb_device *, bool); -int ready_saa(struct usb_device *); -int merit_saa(struct usb_device *); -int check_vt(struct usb_device *); -int select_input(struct usb_device *, int, int); -int set_resolution(struct usb_device *, - u16, u16, u16, u16); - -int read_saa(struct usb_device *, u16); -int read_stk(struct usb_device *, u32); -int write_saa(struct usb_device *, u16, u16); -int write_000(struct usb_device *, u16, u16); -int start_100(struct usb_device *); -int stop_100(struct usb_device *); -int write_300(struct usb_device *); -int read_vt(struct usb_device *, u16); -int write_vt(struct usb_device *, u16, u16); -int isdongle(struct easycap *); +int audio_gainset(struct usb_device *, s8); + +int wakeup_device(struct usb_device *); + +int setup_stk(struct usb_device *, bool); +int setup_saa(struct usb_device *, bool); +int ready_saa(struct usb_device *); +int merit_saa(struct usb_device *); +int check_vt(struct usb_device *); +int select_input(struct usb_device *, int, int); +int set_resolution(struct usb_device *, u16, u16, u16, u16); + +int read_saa(struct usb_device *, u16); +int write_saa(struct usb_device *, u16, u16); +int start_100(struct usb_device *); +int stop_100(struct usb_device *); +int isdongle(struct easycap *); /*---------------------------------------------------------------------------*/ diff --git a/drivers/staging/media/easycap/easycap_ioctl.c b/drivers/staging/media/easycap/easycap_ioctl.c index c99addf..f5bc741 100644 --- a/drivers/staging/media/easycap/easycap_ioctl.c +++ b/drivers/staging/media/easycap/easycap_ioctl.c @@ -854,7 +854,7 @@ int adjust_hue(struct easycap *peasycap, int value) return -ENOENT; } /*****************************************************************************/ -int adjust_volume(struct easycap *peasycap, int value) +static int adjust_volume(struct easycap *peasycap, int value) { s8 mood; int i1; diff --git a/drivers/staging/media/easycap/easycap_low.c b/drivers/staging/media/easycap/easycap_low.c index 0385735..02bb2e5 100644 --- a/drivers/staging/media/easycap/easycap_low.c +++ b/drivers/staging/media/easycap/easycap_low.c @@ -40,6 +40,7 @@ #include "easycap.h" + #define GET(X, Y, Z) do { \ int __rc; \ *(Z) = (u16)0; \ @@ -355,101 +356,6 @@ static int wait_i2c(struct usb_device *p) } /****************************************************************************/ -int confirm_resolution(struct usb_device *p) -{ - u8 get0, get1, get2, get3, get4, get5, get6, get7; - - if (!p) - return -ENODEV; - GET(p, 0x0110, &get0); - GET(p, 0x0111, &get1); - GET(p, 0x0112, &get2); - GET(p, 0x0113, &get3); - GET(p, 0x0114, &get4); - GET(p, 0x0115, &get5); - GET(p, 0x0116, &get6); - GET(p, 0x0117, &get7); - JOT(8, "0x%03X, 0x%03X, " - "0x%03X, 0x%03X, " - "0x%03X, 0x%03X, " - "0x%03X, 0x%03X\n", - get0, get1, get2, get3, get4, get5, get6, get7); - JOT(8, "....cf PAL_720x526: " - "0x%03X, 0x%03X, " - "0x%03X, 0x%03X, " - "0x%03X, 0x%03X, " - "0x%03X, 0x%03X\n", - 0x000, 0x000, 0x001, 0x000, 0x5A0, 0x005, 0x121, 0x001); - JOT(8, "....cf PAL_704x526: " - "0x%03X, 0x%03X, " - "0x%03X, 0x%03X, " - "0x%03X, 0x%03X, " - "0x%03X, 0x%03X\n", - 0x004, 0x000, 0x001, 0x000, 0x584, 0x005, 0x121, 0x001); - JOT(8, "....cf VGA_640x480: " - "0x%03X, 0x%03X, " - "0x%03X, 0x%03X, " - "0x%03X, 0x%03X, " - "0x%03X, 0x%03X\n", - 0x008, 0x000, 0x020, 0x000, 0x508, 0x005, 0x110, 0x001); - return 0; -} -/****************************************************************************/ -int confirm_stream(struct usb_device *p) -{ - u16 get2; - u8 igot; - - if (!p) - return -ENODEV; - GET(p, 0x0100, &igot); get2 = 0x80 & igot; - if (0x80 == get2) - JOT(8, "confirm_stream: OK\n"); - else - JOT(8, "confirm_stream: STUCK\n"); - return 0; -} -/****************************************************************************/ -int setup_stk(struct usb_device *p, bool ntsc) -{ - int i; - const struct stk1160config *cfg; - if (!p) - return -ENODEV; - cfg = (ntsc) ? stk1160configNTSC : stk1160configPAL; - for (i = 0; cfg[i].reg != 0xFFF; i++) - SET(p, cfg[i].reg, cfg[i].set); - - write_300(p); - - return 0; -} -/****************************************************************************/ -int setup_saa(struct usb_device *p, bool ntsc) -{ - int i, ir; - const struct saa7113config *cfg; - if (!p) - return -ENODEV; - cfg = (ntsc) ? saa7113configNTSC : saa7113configPAL; - for (i = 0; cfg[i].reg != 0xFF; i++) - ir = write_saa(p, cfg[i].reg, cfg[i].set); - return 0; -} -/****************************************************************************/ -int write_000(struct usb_device *p, u16 set2, u16 set0) -{ - u8 igot0, igot2; - - if (!p) - return -ENODEV; - GET(p, 0x0002, &igot2); - GET(p, 0x0000, &igot0); - SET(p, 0x0002, set2); - SET(p, 0x0000, set0); - return 0; -} -/****************************************************************************/ int write_saa(struct usb_device *p, u16 reg0, u16 set0) { if (!p) @@ -470,8 +376,7 @@ int write_saa(struct usb_device *p, u16 reg0, u16 set0) * REGISTER 504: TARGET ADDRESS ON VT1612A */ /*--------------------------------------------------------------------------*/ -int -write_vt(struct usb_device *p, u16 reg0, u16 set0) +static int write_vt(struct usb_device *p, u16 reg0, u16 set0) { u8 igot; u16 got502, got503; @@ -508,7 +413,7 @@ write_vt(struct usb_device *p, u16 reg0, u16 set0) * REGISTER 504: TARGET ADDRESS ON VT1612A */ /*--------------------------------------------------------------------------*/ -int read_vt(struct usb_device *p, u16 reg0) +static int read_vt(struct usb_device *p, u16 reg0) { u8 igot; u16 got502, got503; @@ -532,7 +437,7 @@ int read_vt(struct usb_device *p, u16 reg0) * THESE APPEAR TO HAVE NO EFFECT ON EITHER VIDEO OR AUDIO. */ /*--------------------------------------------------------------------------*/ -int write_300(struct usb_device *p) +static int write_300(struct usb_device *p) { if (!p) return -ENODEV; @@ -545,32 +450,32 @@ int write_300(struct usb_device *p) return 0; } /****************************************************************************/ -/*--------------------------------------------------------------------------*/ -/* - * NOTE: THE FOLLOWING IS NOT CHECKED: - * REGISTER 0x0F, WHICH IS INVOLVED IN CHROMINANCE AUTOMATIC GAIN CONTROL. - */ -/*--------------------------------------------------------------------------*/ -int check_saa(struct usb_device *p, bool ntsc) +/****************************************************************************/ +int setup_stk(struct usb_device *p, bool ntsc) { - int i, ir, rc = 0; - struct saa7113config const *cfg; + int i; + const struct stk1160config *cfg; if (!p) return -ENODEV; + cfg = (ntsc) ? stk1160configNTSC : stk1160configPAL; + for (i = 0; cfg[i].reg != 0xFFF; i++) + SET(p, cfg[i].reg, cfg[i].set); - cfg = (ntsc) ? saa7113configNTSC : saa7113configPAL; - for (i = 0; cfg[i].reg != 0xFF; i++) { - if (0x0F == cfg[i].reg) - continue; - ir = read_saa(p, cfg[i].reg); - if (ir != cfg[i].set) { - SAY("SAA register 0x%02X has 0x%02X, expected 0x%02X\n", - cfg[i].reg, ir, cfg[i].set); - rc--; - } - } + write_300(p); - return (rc < -8) ? rc : 0; + return 0; +} +/****************************************************************************/ +int setup_saa(struct usb_device *p, bool ntsc) +{ + int i, ir; + const struct saa7113config *cfg; + if (!p) + return -ENODEV; + cfg = (ntsc) ? saa7113configNTSC : saa7113configPAL; + for (i = 0; cfg[i].reg != 0xFF; i++) + ir = write_saa(p, cfg[i].reg, cfg[i].set); + return 0; } /****************************************************************************/ int merit_saa(struct usb_device *p) @@ -629,44 +534,6 @@ int ready_saa(struct usb_device *p) return 0; } /****************************************************************************/ -/*--------------------------------------------------------------------------*/ -/* - * NOTE: THE FOLLOWING ARE NOT CHECKED: - * REGISTERS 0x000, 0x002: FUNCTIONALITY IS NOT KNOWN - * REGISTER 0x100: ACCEPT ALSO (0x80 | stk1160config....[.].set) - */ -/*--------------------------------------------------------------------------*/ -int check_stk(struct usb_device *p, bool ntsc) -{ - int i, ir; - const struct stk1160config *cfg; - - if (!p) - return -ENODEV; - cfg = (ntsc) ? stk1160configNTSC : stk1160configPAL; - - for (i = 0; 0xFFF != cfg[i].reg; i++) { - if (0x000 == cfg[i].reg || 0x002 == cfg[i].reg) - continue; - - - ir = read_stk(p, cfg[i].reg); - if (0x100 == cfg[i].reg) { - if ((ir != (0xFF & cfg[i].set)) && - (ir != (0x80 | (0xFF & cfg[i].set))) && - (0xFFFF != cfg[i].set)) { - SAY("STK reg[0x%03X]=0x%02X expected 0x%02X\n", - cfg[i].reg, ir, cfg[i].set); - } - continue; - } - if ((ir != (0xFF & cfg[i].set)) && (0xFFFF != cfg[i].set)) - SAY("STK register 0x%03X has 0x%02X,expected 0x%02X\n", - cfg[i].reg, ir, cfg[i].set); - } - return 0; -} -/****************************************************************************/ int read_saa(struct usb_device *p, u16 reg0) { u8 igot; @@ -682,7 +549,7 @@ int read_saa(struct usb_device *p, u16 reg0) return igot; } /****************************************************************************/ -int read_stk(struct usb_device *p, u32 reg0) +static int read_stk(struct usb_device *p, u32 reg0) { u8 igot; @@ -692,27 +559,7 @@ int read_stk(struct usb_device *p, u32 reg0) GET(p, reg0, &igot); return igot; } -/****************************************************************************/ -/*--------------------------------------------------------------------------*/ -/* - * HARDWARE USERSPACE INPUT NUMBER PHYSICAL INPUT DRIVER input VALUE - * - * CVBS+S-VIDEO 0 or 1 CVBS 1 - * FOUR-CVBS 0 or 1 CVBS1 1 - * FOUR-CVBS 2 CVBS2 2 - * FOUR-CVBS 3 CVBS3 3 - * FOUR-CVBS 4 CVBS4 4 - * CVBS+S-VIDEO 5 S-VIDEO 5 - * - * WHEN 5==input THE ARGUMENT mode MUST ALSO BE SUPPLIED: - * - * mode 7 => GAIN TO BE SET EXPLICITLY USING REGISTER 0x05 (UNTESTED) - * mode 9 => USE AUTOMATIC GAIN CONTROL (DEFAULT) - * -*/ -/*---------------------------------------------------------------------------*/ -int -select_input(struct usb_device *p, int input, int mode) +int select_input(struct usb_device *p, int input, int mode) { int ir; @@ -1115,15 +962,3 @@ int audio_gainset(struct usb_device *pusb_device, s8 loud) return 0; } /*****************************************************************************/ -int audio_gainget(struct usb_device *pusb_device) -{ - int igot; - - if (!pusb_device) - return -ENODEV; - igot = read_vt(pusb_device, 0x001C); - if (0 > igot) - SAY("ERROR: failed to read VT1612A register 0x1C\n"); - return igot; -} -/*****************************************************************************/ diff --git a/drivers/staging/media/easycap/easycap_main.c b/drivers/staging/media/easycap/easycap_main.c index a45c0b5..94fd116 100644 --- a/drivers/staging/media/easycap/easycap_main.c +++ b/drivers/staging/media/easycap/easycap_main.c @@ -66,6 +66,10 @@ struct easycap_dongle easycapdc60_dongle[DONGLE_MANY]; static struct mutex mutex_dongle; static void easycap_complete(struct urb *purb); static int reset(struct easycap *peasycap); +static int field2frame(struct easycap *peasycap); +static int redaub(struct easycap *peasycap, + void *pad, void *pex, int much, int more, + u8 mask, u8 margin, bool isuy); const char *strerror(int err) { @@ -1211,8 +1215,7 @@ int easycap_dqbuf(struct easycap *peasycap, int mode) * CHOOSES THE OPTION V4L2_FIELD_INTERLACED. */ /*---------------------------------------------------------------------------*/ -int -field2frame(struct easycap *peasycap) +static int field2frame(struct easycap *peasycap) { void *pex, *pad; @@ -1601,9 +1604,9 @@ field2frame(struct easycap *peasycap) * REDUCE CODE LENGTH WILL GENERALLY IMPAIR RUNTIME PERFORMANCE. BEWARE. */ /*---------------------------------------------------------------------------*/ -int -redaub(struct easycap *peasycap, void *pad, void *pex, int much, int more, - u8 mask, u8 margin, bool isuy) +static int redaub(struct easycap *peasycap, + void *pad, void *pex, int much, int more, + u8 mask, u8 margin, bool isuy) { static s32 ay[256], bu[256], rv[256], gu[256], gv[256]; u8 *pcache; diff --git a/drivers/staging/media/easycap/easycap_sound.c b/drivers/staging/media/easycap/easycap_sound.c index b22bb39..70813a5 100644 --- a/drivers/staging/media/easycap/easycap_sound.c +++ b/drivers/staging/media/easycap/easycap_sound.c @@ -56,6 +56,152 @@ static const struct snd_pcm_hardware alsa_hardware = { }; +/*---------------------------------------------------------------------------*/ +/* + * SUBMIT ALL AUDIO URBS. + */ +/*---------------------------------------------------------------------------*/ +static int submit_audio_urbs(struct easycap *peasycap) +{ + struct data_urb *pdata_urb; + struct urb *purb; + struct list_head *plist_head; + int j, isbad, nospc, m, rc; + int isbuf; + + if (!peasycap) { + SAY("ERROR: peasycap is NULL\n"); + return -EFAULT; + } + if (!peasycap->purb_audio_head) { + SAM("ERROR: peasycap->urb_audio_head uninitialized\n"); + return -EFAULT; + } + if (!peasycap->pusb_device) { + SAM("ERROR: peasycap->pusb_device is NULL\n"); + return -EFAULT; + } + + if (peasycap->audio_isoc_streaming) { + JOM(4, "already streaming audio urbs\n"); + return 0; + } + + JOM(4, "initial submission of all audio urbs\n"); + rc = usb_set_interface(peasycap->pusb_device, + peasycap->audio_interface, + peasycap->audio_altsetting_on); + JOM(8, "usb_set_interface(.,%i,%i) returned %i\n", + peasycap->audio_interface, + peasycap->audio_altsetting_on, rc); + + isbad = 0; + nospc = 0; + m = 0; + list_for_each(plist_head, peasycap->purb_audio_head) { + pdata_urb = list_entry(plist_head, struct data_urb, list_head); + if (pdata_urb && pdata_urb->purb) { + purb = pdata_urb->purb; + isbuf = pdata_urb->isbuf; + + purb->interval = 1; + purb->dev = peasycap->pusb_device; + purb->pipe = usb_rcvisocpipe(peasycap->pusb_device, + peasycap->audio_endpointnumber); + purb->transfer_flags = URB_ISO_ASAP; + purb->transfer_buffer = peasycap->audio_isoc_buffer[isbuf].pgo; + purb->transfer_buffer_length = peasycap->audio_isoc_buffer_size; + purb->complete = easycap_alsa_complete; + purb->context = peasycap; + purb->start_frame = 0; + purb->number_of_packets = peasycap->audio_isoc_framesperdesc; + for (j = 0; j < peasycap->audio_isoc_framesperdesc; j++) { + purb->iso_frame_desc[j].offset = j * peasycap->audio_isoc_maxframesize; + purb->iso_frame_desc[j].length = peasycap->audio_isoc_maxframesize; + } + + rc = usb_submit_urb(purb, GFP_KERNEL); + if (rc) { + isbad++; + SAM("ERROR: usb_submit_urb() failed" + " for urb with rc: -%s: %d\n", + strerror(rc), rc); + } else { + m++; + } + } else { + isbad++; + } + } + if (nospc) { + SAM("-ENOSPC=usb_submit_urb() for %i urbs\n", nospc); + SAM("..... possibly inadequate USB bandwidth\n"); + peasycap->audio_eof = 1; + } + if (isbad) { + JOM(4, "attempting cleanup instead of submitting\n"); + list_for_each(plist_head, (peasycap->purb_audio_head)) { + pdata_urb = list_entry(plist_head, struct data_urb, list_head); + if (pdata_urb && pdata_urb->purb) + usb_kill_urb(pdata_urb->purb); + } + peasycap->audio_isoc_streaming = 0; + } else { + peasycap->audio_isoc_streaming = m; + JOM(4, "submitted %i audio urbs\n", m); + } + + return 0; +} +/*---------------------------------------------------------------------------*/ +/* + * COMMON AUDIO INITIALIZATION + */ +/*---------------------------------------------------------------------------*/ +static int easycap_sound_setup(struct easycap *peasycap) +{ + int rc; + + JOM(4, "starting initialization\n"); + + if (!peasycap) { + SAY("ERROR: peasycap is NULL.\n"); + return -EFAULT; + } + if (!peasycap->pusb_device) { + SAM("ERROR: peasycap->pusb_device is NULL\n"); + return -ENODEV; + } + JOM(16, "0x%08lX=peasycap->pusb_device\n", (long int)peasycap->pusb_device); + + rc = audio_setup(peasycap); + JOM(8, "audio_setup() returned %i\n", rc); + + if (!peasycap->pusb_device) { + SAM("ERROR: peasycap->pusb_device has become NULL\n"); + return -ENODEV; + } +/*---------------------------------------------------------------------------*/ + if (!peasycap->pusb_device) { + SAM("ERROR: peasycap->pusb_device has become NULL\n"); + return -ENODEV; + } + rc = usb_set_interface(peasycap->pusb_device, peasycap->audio_interface, + peasycap->audio_altsetting_on); + JOM(8, "usb_set_interface(.,%i,%i) returned %i\n", peasycap->audio_interface, + peasycap->audio_altsetting_on, rc); + + rc = wakeup_device(peasycap->pusb_device); + JOM(8, "wakeup_device() returned %i\n", rc); + + peasycap->audio_eof = 0; + peasycap->audio_idle = 0; + + submit_audio_urbs(peasycap); + + JOM(4, "finished initialization\n"); + return 0; +} /*****************************************************************************/ /*---------------------------------------------------------------------------*/ /* @@ -615,202 +761,3 @@ int easycap_alsa_probe(struct easycap *peasycap) return 0; } -/*****************************************************************************/ -/*****************************************************************************/ -/*****************************************************************************/ -/*****************************************************************************/ -/*****************************************************************************/ -/*****************************************************************************/ -/*---------------------------------------------------------------------------*/ -/* - * COMMON AUDIO INITIALIZATION - */ -/*---------------------------------------------------------------------------*/ -int -easycap_sound_setup(struct easycap *peasycap) -{ - int rc; - - JOM(4, "starting initialization\n"); - - if (!peasycap) { - SAY("ERROR: peasycap is NULL.\n"); - return -EFAULT; - } - if (!peasycap->pusb_device) { - SAM("ERROR: peasycap->pusb_device is NULL\n"); - return -ENODEV; - } - JOM(16, "0x%08lX=peasycap->pusb_device\n", (long int)peasycap->pusb_device); - - rc = audio_setup(peasycap); - JOM(8, "audio_setup() returned %i\n", rc); - - if (!peasycap->pusb_device) { - SAM("ERROR: peasycap->pusb_device has become NULL\n"); - return -ENODEV; - } -/*---------------------------------------------------------------------------*/ - if (!peasycap->pusb_device) { - SAM("ERROR: peasycap->pusb_device has become NULL\n"); - return -ENODEV; - } - rc = usb_set_interface(peasycap->pusb_device, peasycap->audio_interface, - peasycap->audio_altsetting_on); - JOM(8, "usb_set_interface(.,%i,%i) returned %i\n", peasycap->audio_interface, - peasycap->audio_altsetting_on, rc); - - rc = wakeup_device(peasycap->pusb_device); - JOM(8, "wakeup_device() returned %i\n", rc); - - peasycap->audio_eof = 0; - peasycap->audio_idle = 0; - - submit_audio_urbs(peasycap); - - JOM(4, "finished initialization\n"); - return 0; -} -/*****************************************************************************/ -/*---------------------------------------------------------------------------*/ -/* - * SUBMIT ALL AUDIO URBS. - */ -/*---------------------------------------------------------------------------*/ -int -submit_audio_urbs(struct easycap *peasycap) -{ - struct data_urb *pdata_urb; - struct urb *purb; - struct list_head *plist_head; - int j, isbad, nospc, m, rc; - int isbuf; - - if (!peasycap) { - SAY("ERROR: peasycap is NULL\n"); - return -EFAULT; - } - if (!peasycap->purb_audio_head) { - SAM("ERROR: peasycap->urb_audio_head uninitialized\n"); - return -EFAULT; - } - if (!peasycap->pusb_device) { - SAM("ERROR: peasycap->pusb_device is NULL\n"); - return -EFAULT; - } - - if (peasycap->audio_isoc_streaming) { - JOM(4, "already streaming audio urbs\n"); - return 0; - } - - JOM(4, "initial submission of all audio urbs\n"); - rc = usb_set_interface(peasycap->pusb_device, - peasycap->audio_interface, - peasycap->audio_altsetting_on); - JOM(8, "usb_set_interface(.,%i,%i) returned %i\n", - peasycap->audio_interface, - peasycap->audio_altsetting_on, rc); - - isbad = 0; - nospc = 0; - m = 0; - list_for_each(plist_head, peasycap->purb_audio_head) { - pdata_urb = list_entry(plist_head, struct data_urb, list_head); - if (pdata_urb && pdata_urb->purb) { - purb = pdata_urb->purb; - isbuf = pdata_urb->isbuf; - - purb->interval = 1; - purb->dev = peasycap->pusb_device; - purb->pipe = usb_rcvisocpipe(peasycap->pusb_device, - peasycap->audio_endpointnumber); - purb->transfer_flags = URB_ISO_ASAP; - purb->transfer_buffer = peasycap->audio_isoc_buffer[isbuf].pgo; - purb->transfer_buffer_length = peasycap->audio_isoc_buffer_size; - purb->complete = easycap_alsa_complete; - purb->context = peasycap; - purb->start_frame = 0; - purb->number_of_packets = peasycap->audio_isoc_framesperdesc; - for (j = 0; j < peasycap->audio_isoc_framesperdesc; j++) { - purb->iso_frame_desc[j].offset = j * peasycap->audio_isoc_maxframesize; - purb->iso_frame_desc[j].length = peasycap->audio_isoc_maxframesize; - } - - rc = usb_submit_urb(purb, GFP_KERNEL); - if (rc) { - isbad++; - SAM("ERROR: usb_submit_urb() failed" - " for urb with rc: -%s: %d\n", - strerror(rc), rc); - } else { - m++; - } - } else { - isbad++; - } - } - if (nospc) { - SAM("-ENOSPC=usb_submit_urb() for %i urbs\n", nospc); - SAM("..... possibly inadequate USB bandwidth\n"); - peasycap->audio_eof = 1; - } - if (isbad) { - JOM(4, "attempting cleanup instead of submitting\n"); - list_for_each(plist_head, (peasycap->purb_audio_head)) { - pdata_urb = list_entry(plist_head, struct data_urb, list_head); - if (pdata_urb && pdata_urb->purb) - usb_kill_urb(pdata_urb->purb); - } - peasycap->audio_isoc_streaming = 0; - } else { - peasycap->audio_isoc_streaming = m; - JOM(4, "submitted %i audio urbs\n", m); - } - - return 0; -} -/*****************************************************************************/ -/*---------------------------------------------------------------------------*/ -/* - * KILL ALL AUDIO URBS. - */ -/*---------------------------------------------------------------------------*/ -int -kill_audio_urbs(struct easycap *peasycap) -{ - int m; - struct list_head *plist_head; - struct data_urb *pdata_urb; - - if (!peasycap) { - SAY("ERROR: peasycap is NULL\n"); - return -EFAULT; - } - - if (!peasycap->audio_isoc_streaming) { - JOM(8, "%i=audio_isoc_streaming, no audio urbs killed\n", - peasycap->audio_isoc_streaming); - return 0; - } - - if (!peasycap->purb_audio_head) { - SAM("ERROR: peasycap->purb_audio_head is NULL\n"); - return -EFAULT; - } - - peasycap->audio_isoc_streaming = 0; - JOM(4, "killing audio urbs\n"); - m = 0; - list_for_each(plist_head, (peasycap->purb_audio_head)) { - pdata_urb = list_entry(plist_head, struct data_urb, list_head); - if (pdata_urb && pdata_urb->purb) { - usb_kill_urb(pdata_urb->purb); - m++; - } - } - JOM(4, "%i audio urbs killed\n", m); - - return 0; -} -/*****************************************************************************/ -- cgit v0.10.2 From 47cefc21ef4ce2c8caec931a2dbe7fef1727fc31 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Wed, 9 Nov 2011 08:26:33 -0300 Subject: [media] easycap: remove linux/version.h include from easycap_ioctl.c Signed-off-by: Tomas Winkler Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/staging/media/easycap/easycap_ioctl.c b/drivers/staging/media/easycap/easycap_ioctl.c index f5bc741..acb9c84 100644 --- a/drivers/staging/media/easycap/easycap_ioctl.c +++ b/drivers/staging/media/easycap/easycap_ioctl.c @@ -25,7 +25,6 @@ */ /*****************************************************************************/ -#include #include "easycap.h" /*--------------------------------------------------------------------------*/ -- cgit v0.10.2 From 7dbb3920252dcb3662e934b134ccb5129f62cbad Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Wed, 9 Nov 2011 08:26:34 -0300 Subject: [media] easycap: compress initialization tables 1. saa and stk initialization tables are less then 256 entries 2. stk table can fit into u16 and saa into u8 size before text data bss dec hex filename 105687 1072 1134800 1241559 12f1d7 easycap.ko size after text data bss dec hex filename 97919 1072 1134800 1233791 12d37f easycap.ko Signed-off-by: Tomas Winkler Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/staging/media/easycap/easycap_low.c b/drivers/staging/media/easycap/easycap_low.c index 02bb2e5..ef37de8 100644 --- a/drivers/staging/media/easycap/easycap_low.c +++ b/drivers/staging/media/easycap/easycap_low.c @@ -60,9 +60,9 @@ /*--------------------------------------------------------------------------*/ static const struct stk1160config { - int reg; - int set; -} stk1160configPAL[256] = { + u16 reg; + u16 set; +} stk1160configPAL[] = { {0x000, 0x0098}, {0x002, 0x0093}, @@ -104,7 +104,7 @@ static const struct stk1160config { {0xFFF, 0xFFFF} }; /*--------------------------------------------------------------------------*/ -static const struct stk1160config stk1160configNTSC[256] = { +static const struct stk1160config stk1160configNTSC[] = { {0x000, 0x0098}, {0x002, 0x0093}, @@ -147,9 +147,9 @@ static const struct stk1160config stk1160configNTSC[256] = { }; /*--------------------------------------------------------------------------*/ static const struct saa7113config { - int reg; - int set; -} saa7113configPAL[256] = { + u8 reg; + u8 set; +} saa7113configPAL[] = { {0x01, 0x08}, {0x02, 0x80}, {0x03, 0x33}, @@ -203,7 +203,7 @@ static const struct saa7113config { {0xFF, 0xFF} }; /*--------------------------------------------------------------------------*/ -static const struct saa7113config saa7113configNTSC[256] = { +static const struct saa7113config saa7113configNTSC[] = { {0x01, 0x08}, {0x02, 0x80}, {0x03, 0x33}, -- cgit v0.10.2 From 101dca425da49edb3093000d72490216fa322911 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Wed, 9 Nov 2011 08:26:35 -0300 Subject: [media] easycap: streamline the code change statements of types if (err) return err else do something and if (ok) do something else return err into if (err) return err do something Signed-off-by: Tomas Winkler Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/staging/media/easycap/easycap_ioctl.c b/drivers/staging/media/easycap/easycap_ioctl.c index acb9c84..ccab5ca 100644 --- a/drivers/staging/media/easycap/easycap_ioctl.c +++ b/drivers/staging/media/easycap/easycap_ioctl.c @@ -666,16 +666,15 @@ int adjust_brightness(struct easycap *peasycap, int value) peasycap->inputset[peasycap->input].brightness_ok = 1; } else JOM(8, "%i=peasycap->input\n", peasycap->input); + mood = 0x00FF & (unsigned int)peasycap->brightness; - if (!write_saa(peasycap->pusb_device, 0x0A, mood)) { - SAM("adjusting brightness to 0x%02X\n", mood); - return 0; - } else { + if (write_saa(peasycap->pusb_device, 0x0A, mood)) { SAM("WARNING: failed to adjust brightness " "to 0x%02X\n", mood); return -ENOENT; } - break; + SAM("adjusting brightness to 0x%02X\n", mood); + return 0; } i1++; } @@ -725,15 +724,13 @@ int adjust_contrast(struct easycap *peasycap, int value) JOM(8, "%i=peasycap->input\n", peasycap->input); mood = 0x00FF & (unsigned int) (peasycap->contrast - 128); - if (!write_saa(peasycap->pusb_device, 0x0B, mood)) { - SAM("adjusting contrast to 0x%02X\n", mood); - return 0; - } else { + if (write_saa(peasycap->pusb_device, 0x0B, mood)) { SAM("WARNING: failed to adjust contrast to " "0x%02X\n", mood); return -ENOENT; } - break; + SAM("adjusting contrast to 0x%02X\n", mood); + return 0; } i1++; } @@ -783,14 +780,13 @@ int adjust_saturation(struct easycap *peasycap, int value) } else JOM(8, "%i=peasycap->input\n", peasycap->input); mood = 0x00FF & (unsigned int) (peasycap->saturation - 128); - if (!write_saa(peasycap->pusb_device, 0x0C, mood)) { - SAM("adjusting saturation to 0x%02X\n", mood); - return 0; - } else { + if (write_saa(peasycap->pusb_device, 0x0C, mood)) { SAM("WARNING: failed to adjust saturation to " "0x%02X\n", mood); return -ENOENT; } + SAM("adjusting saturation to 0x%02X\n", mood); + return 0; break; } i1++; @@ -838,13 +834,12 @@ int adjust_hue(struct easycap *peasycap, int value) JOM(8, "%i=peasycap->input\n", peasycap->input); i2 = peasycap->hue - 128; mood = 0x00FF & ((int) i2); - if (!write_saa(peasycap->pusb_device, 0x0D, mood)) { - SAM("adjusting hue to 0x%02X\n", mood); - return 0; - } else { + if (write_saa(peasycap->pusb_device, 0x0D, mood)) { SAM("WARNING: failed to adjust hue to 0x%02X\n", mood); return -ENOENT; } + SAM("adjusting hue to 0x%02X\n", mood); + return 0; break; } i1++; @@ -885,14 +880,12 @@ static int adjust_volume(struct easycap *peasycap, int value) ((31 < peasycap->volume) ? 31 : (s8) peasycap->volume); if (!audio_gainset(peasycap->pusb_device, mood)) { - SAM("adjusting volume to 0x%02X\n", mood); - return 0; - } else { SAM("WARNING: failed to adjust volume to " "0x%2X\n", mood); return -ENOENT; } - break; + SAM("adjusting volume to 0x%02X\n", mood); + return 0; } i1++; } diff --git a/drivers/staging/media/easycap/easycap_low.c b/drivers/staging/media/easycap/easycap_low.c index ef37de8..212830b 100644 --- a/drivers/staging/media/easycap/easycap_low.c +++ b/drivers/staging/media/easycap/easycap_low.c @@ -514,22 +514,22 @@ int ready_saa(struct usb_device *p) msleep(marktime); j++; } + if (max == j) return -1; + + if (0x20 & rc) { + rate = 2; + JOT(8, "hardware detects 60 Hz\n"); + } else { + rate = 0; + JOT(8, "hardware detects 50 Hz\n"); + } + if (0x80 & rc) + JOT(8, "hardware detects interlacing\n"); else { - if (0x20 & rc) { - rate = 2; - JOT(8, "hardware detects 60 Hz\n"); - } else { - rate = 0; - JOT(8, "hardware detects 50 Hz\n"); - } - if (0x80 & rc) - JOT(8, "hardware detects interlacing\n"); - else { - rate++; - JOT(8, "hardware detects no interlacing\n"); - } + rate++; + JOT(8, "hardware detects no interlacing\n"); } return 0; } diff --git a/drivers/staging/media/easycap/easycap_main.c b/drivers/staging/media/easycap/easycap_main.c index 94fd116..044c762 100644 --- a/drivers/staging/media/easycap/easycap_main.c +++ b/drivers/staging/media/easycap/easycap_main.c @@ -165,14 +165,13 @@ static int easycap_open(struct inode *inode, struct file *file) if (!peasycap->pusb_device) { SAM("ERROR: peasycap->pusb_device is NULL\n"); return -EFAULT; - } else { - JOM(16, "peasycap->pusb_device=%p\n", peasycap->pusb_device); } + + JOM(16, "peasycap->pusb_device=%p\n", peasycap->pusb_device); + file->private_data = peasycap; rc = wakeup_device(peasycap->pusb_device); - if (0 == rc) - JOM(8, "wakeup_device() OK\n"); - else { + if (rc) { SAM("ERROR: wakeup_device() rc = %i\n", rc); if (-ENODEV == rc) SAM("ERROR: wakeup_device() returned -ENODEV\n"); @@ -180,6 +179,7 @@ static int easycap_open(struct inode *inode, struct file *file) SAM("ERROR: wakeup_device() rc = %i\n", rc); return rc; } + JOM(8, "wakeup_device() OK\n"); peasycap->input = 0; rc = reset(peasycap); if (rc) { @@ -987,11 +987,11 @@ static unsigned int easycap_poll(struct file *file, poll_table *wait) rc = easycap_dqbuf(peasycap, 0); peasycap->polled = 1; mutex_unlock(&easycapdc60_dongle[kd].mutex_video); - if (0 == rc) - return POLLIN | POLLRDNORM; - else + if (rc) return POLLERR; - } + + return POLLIN | POLLRDNORM; +} /*****************************************************************************/ /*---------------------------------------------------------------------------*/ /* @@ -2920,6 +2920,7 @@ static int easycap_usb_probe(struct usb_interface *intf, SAY("ERROR: usb_host_interface not found\n"); return -EFAULT; } + interface = &alt->desc; if (!interface) { SAY("ERROR: intf_descriptor is NULL\n"); @@ -2979,38 +2980,30 @@ static int easycap_usb_probe(struct usb_interface *intf, if (mutex_lock_interruptible(&mutex_dongle)) { SAY("ERROR: cannot down mutex_dongle\n"); return -ERESTARTSYS; - } else { -/*---------------------------------------------------------------------------*/ - /* - * FOR INTERFACES 1 AND 2 THE POINTER peasycap WILL NEED TO - * TO BE THE SAME AS THAT ALLOCATED NOW FOR INTERFACE 0. - * - * NORMALLY ndong WILL NOT HAVE CHANGED SINCE INTERFACE 0 WAS - * PROBED, BUT THIS MAY NOT BE THE CASE IF, FOR EXAMPLE, TWO - * EASYCAPs ARE PLUGGED IN SIMULTANEOUSLY. - */ -/*---------------------------------------------------------------------------*/ - for (ndong = 0; ndong < DONGLE_MANY; ndong++) { - if ((!easycapdc60_dongle[ndong].peasycap) && - (!mutex_is_locked(&easycapdc60_dongle - [ndong].mutex_video)) && - (!mutex_is_locked(&easycapdc60_dongle - [ndong].mutex_audio))) { - easycapdc60_dongle[ndong].peasycap = peasycap; - peasycap->isdongle = ndong; - JOM(8, "intf[%i]: peasycap-->easycap" - "_dongle[%i].peasycap\n", - bInterfaceNumber, ndong); - break; - } - } - if (DONGLE_MANY <= ndong) { - SAM("ERROR: too many dongles\n"); - mutex_unlock(&mutex_dongle); - return -ENOMEM; + } + + for (ndong = 0; ndong < DONGLE_MANY; ndong++) { + if ((!easycapdc60_dongle[ndong].peasycap) && + (!mutex_is_locked(&easycapdc60_dongle + [ndong].mutex_video)) && + (!mutex_is_locked(&easycapdc60_dongle + [ndong].mutex_audio))) { + easycapdc60_dongle[ndong].peasycap = peasycap; + peasycap->isdongle = ndong; + JOM(8, "intf[%i]: peasycap-->easycap" + "_dongle[%i].peasycap\n", + bInterfaceNumber, ndong); + break; } + } + + if (DONGLE_MANY <= ndong) { + SAM("ERROR: too many dongles\n"); mutex_unlock(&mutex_dongle); + return -ENOMEM; } + mutex_unlock(&mutex_dongle); + peasycap->allocation_video_struct = sizeof(struct easycap); peasycap->allocation_video_page = 0; peasycap->allocation_video_urb = 0; @@ -3393,11 +3386,10 @@ static int easycap_usb_probe(struct usb_interface *intf, if (!isokalt) { SAM("ERROR: no viable video_altsetting_on\n"); return -ENOENT; - } else { - peasycap->video_altsetting_on = okalt[isokalt - 1]; - JOM(4, "%i=video_altsetting_on <====\n", - peasycap->video_altsetting_on); } + peasycap->video_altsetting_on = okalt[isokalt - 1]; + JOM(4, "%i=video_altsetting_on <====\n", + peasycap->video_altsetting_on); /*---------------------------------------------------------------------------*/ /* * DECIDE THE VIDEO STREAMING PARAMETERS @@ -3483,8 +3475,9 @@ static int easycap_usb_probe(struct usb_interface *intf, SAM("ERROR: Could not allocate frame " "buffer %i page %i\n", k, m); return -ENOMEM; - } else - peasycap->allocation_video_page += 1; + } + + peasycap->allocation_video_page += 1; peasycap->frame_buffer[k][m].pgo = pbuf; } peasycap->frame_buffer[k][m].pto = @@ -3513,11 +3506,11 @@ static int easycap_usb_probe(struct usb_interface *intf, SAM("ERROR: Could not allocate field" " buffer %i page %i\n", k, m); return -ENOMEM; - } - else - peasycap->allocation_video_page += 1; - peasycap->field_buffer[k][m].pgo = pbuf; } + + peasycap->allocation_video_page += 1; + peasycap->field_buffer[k][m].pgo = pbuf; + } peasycap->field_buffer[k][m].pto = peasycap->field_buffer[k][m].pgo; } @@ -3541,9 +3534,9 @@ static int easycap_usb_probe(struct usb_interface *intf, SAM("ERROR: Could not allocate isoc video buffer " "%i\n", k); return -ENOMEM; - } else - peasycap->allocation_video_page += - BIT(VIDEO_ISOC_ORDER); + } + peasycap->allocation_video_page += + BIT(VIDEO_ISOC_ORDER); peasycap->video_isoc_buffer[k].pgo = pbuf; peasycap->video_isoc_buffer[k].pto = @@ -3572,15 +3565,17 @@ static int easycap_usb_probe(struct usb_interface *intf, SAM("ERROR: usb_alloc_urb returned NULL for buffer " "%i\n", k); return -ENOMEM; - } else - peasycap->allocation_video_urb += 1; + } + + peasycap->allocation_video_urb += 1; /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ pdata_urb = kzalloc(sizeof(struct data_urb), GFP_KERNEL); if (!pdata_urb) { SAM("ERROR: Could not allocate struct data_urb.\n"); return -ENOMEM; - } else - peasycap->allocation_video_struct += + } + + peasycap->allocation_video_struct += sizeof(struct data_urb); pdata_urb->purb = purb; @@ -3697,13 +3692,12 @@ static int easycap_usb_probe(struct usb_interface *intf, err("Not able to register with videodev"); videodev_release(&(peasycap->video_device)); return -ENODEV; - } else { - (peasycap->registered_video)++; - SAM("registered with videodev: %i=minor\n", - peasycap->video_device.minor); - peasycap->minor = peasycap->video_device.minor; } -/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ + + peasycap->registered_video++; + SAM("registered with videodev: %i=minor\n", + peasycap->video_device.minor); + peasycap->minor = peasycap->video_device.minor; break; } @@ -3737,11 +3731,10 @@ static int easycap_usb_probe(struct usb_interface *intf, if (!isokalt) { SAM("ERROR: no viable audio_altsetting_on\n"); return -ENOENT; - } else { - peasycap->audio_altsetting_on = okalt[isokalt - 1]; - JOM(4, "%i=audio_altsetting_on <====\n", - peasycap->audio_altsetting_on); } + peasycap->audio_altsetting_on = okalt[isokalt - 1]; + JOM(4, "%i=audio_altsetting_on <====\n", + peasycap->audio_altsetting_on); peasycap->audio_endpointnumber = okepn[isokalt - 1]; JOM(4, "%i=audio_endpointnumber\n", peasycap->audio_endpointnumber); @@ -3850,8 +3843,8 @@ static int easycap_usb_probe(struct usb_interface *intf, SAM("ERROR: Could not allocate isoc audio buffer " "%i\n", k); return -ENOMEM; - } else - peasycap->allocation_audio_page += + } + peasycap->allocation_audio_page += BIT(AUDIO_ISOC_ORDER); peasycap->audio_isoc_buffer[k].pgo = pbuf; -- cgit v0.10.2 From 7dfdae8e32a26ef3b3aa8d114d2fed93d7680169 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Wed, 9 Nov 2011 08:26:36 -0300 Subject: [media] easycap: drop initializations to 0 in the probe functions peasycap was allocated using kzalloc so drop all to zero initializations Signed-off-by: Tomas Winkler Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/staging/media/easycap/easycap_main.c b/drivers/staging/media/easycap/easycap_main.c index 044c762..8da1682 100644 --- a/drivers/staging/media/easycap/easycap_main.c +++ b/drivers/staging/media/easycap/easycap_main.c @@ -3005,11 +3005,6 @@ static int easycap_usb_probe(struct usb_interface *intf, mutex_unlock(&mutex_dongle); peasycap->allocation_video_struct = sizeof(struct easycap); - peasycap->allocation_video_page = 0; - peasycap->allocation_video_urb = 0; - peasycap->allocation_audio_struct = 0; - peasycap->allocation_audio_page = 0; - peasycap->allocation_audio_urb = 0; /*---------------------------------------------------------------------------*/ /* @@ -3019,7 +3014,6 @@ static int easycap_usb_probe(struct usb_interface *intf, peasycap->pusb_device = usbdev; peasycap->pusb_interface = intf; - peasycap->ilk = 0; peasycap->microphone = false; peasycap->video_interface = -1; @@ -3038,11 +3032,6 @@ static int easycap_usb_probe(struct usb_interface *intf, peasycap->frame_buffer_many = FRAME_BUFFER_MANY; - for (k = 0; k < INPUT_MANY; k++) - peasycap->lost[k] = 0; - peasycap->skip = 0; - peasycap->skipped = 0; - peasycap->offerfields = 0; /*---------------------------------------------------------------------------*/ /* * DYNAMICALLY FILL IN THE AVAILABLE FORMATS ... @@ -3054,22 +3043,10 @@ static int easycap_usb_probe(struct usb_interface *intf, return -EFAULT; } JOM(4, "%i formats available\n", rc); -/*---------------------------------------------------------------------------*/ -/* - * ... AND POPULATE easycap.inputset[] -*/ -/*---------------------------------------------------------------------------*/ - /* FIXME: maybe we just use memset 0 */ + + /* ... AND POPULATE easycap.inputset[] */ + inputset = peasycap->inputset; - for (k = 0; k < INPUT_MANY; k++) { - inputset[k].input_ok = 0; - inputset[k].standard_offset_ok = 0; - inputset[k].format_offset_ok = 0; - inputset[k].brightness_ok = 0; - inputset[k].contrast_ok = 0; - inputset[k].saturation_ok = 0; - inputset[k].hue_ok = 0; - } fmtidx = peasycap->ntsc ? NTSC_M : PAL_BGHIN; m = 0; -- cgit v0.10.2 From 8b1fad2f046fb825046fee3a41885a70123de988 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Wed, 9 Nov 2011 08:26:37 -0300 Subject: [media] easycap: use usb_kill_urb wrapper functions 1. kill_video_usb can be used in all places where video urbs are killed and reduce code repetition 2. remove unnecessary check for easycap == NULL in the function as it is always checked by the calling function 3. rename the function to easycap_video_kill_urb to reduce possibility of name conflict 4. implement also easycap_audio_kill_urb 5. simplify freeing urbs Signed-off-by: Tomas Winkler Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/staging/media/easycap/easycap.h b/drivers/staging/media/easycap/easycap.h index 899e572..1d98d31 100644 --- a/drivers/staging/media/easycap/easycap.h +++ b/drivers/staging/media/easycap/easycap.h @@ -472,7 +472,7 @@ struct easycap { long easycap_unlocked_ioctl(struct file *, unsigned int, unsigned long); int easycap_dqbuf(struct easycap *, int); int submit_video_urbs(struct easycap *); -int kill_video_urbs(struct easycap *); +int easycap_video_kill_urbs(struct easycap *); void easycap_testcard(struct easycap *, int); int fillin_formats(void); int newinput(struct easycap *, int); @@ -489,6 +489,7 @@ int adjust_hue(struct easycap *, int); */ /*---------------------------------------------------------------------------*/ int easycap_alsa_probe(struct easycap *); +int easycap_audio_kill_urbs(struct easycap *); void easycap_alsa_complete(struct urb *); int audio_setup(struct easycap *); /*---------------------------------------------------------------------------*/ diff --git a/drivers/staging/media/easycap/easycap_ioctl.c b/drivers/staging/media/easycap/easycap_ioctl.c index ccab5ca..90d4384 100644 --- a/drivers/staging/media/easycap/easycap_ioctl.c +++ b/drivers/staging/media/easycap/easycap_ioctl.c @@ -124,7 +124,7 @@ int adjust_standard(struct easycap *peasycap, v4l2_std_id std_id) } if (peasycap->video_isoc_streaming) { resubmit = true; - kill_video_urbs(peasycap); + easycap_video_kill_urbs(peasycap); } else resubmit = false; /*--------------------------------------------------------------------------*/ @@ -557,7 +557,7 @@ int adjust_format(struct easycap *peasycap, peasycap->bytesperpixel * peasycap->width * peasycap->height; if (peasycap->video_isoc_streaming) { resubmit = true; - kill_video_urbs(peasycap); + easycap_video_kill_urbs(peasycap); } else resubmit = false; /*---------------------------------------------------------------------------*/ diff --git a/drivers/staging/media/easycap/easycap_main.c b/drivers/staging/media/easycap/easycap_main.c index 8da1682..c147c61 100644 --- a/drivers/staging/media/easycap/easycap_main.c +++ b/drivers/staging/media/easycap/easycap_main.c @@ -401,7 +401,7 @@ newinput(struct easycap *peasycap, int input) peasycap->audio_idle = 1; if (peasycap->video_isoc_streaming) { resubmit = true; - kill_video_urbs(peasycap); + easycap_video_kill_urbs(peasycap); } else { resubmit = false; } @@ -620,43 +620,53 @@ int submit_video_urbs(struct easycap *peasycap) peasycap->video_eof = 1; } - if (isbad) { - JOM(4, "attempting cleanup instead of submitting\n"); - list_for_each(plist_head, (peasycap->purb_video_head)) { - pdata_urb = list_entry(plist_head, - struct data_urb, list_head); - if (pdata_urb) { - purb = pdata_urb->purb; - if (purb) - usb_kill_urb(purb); - } - } - peasycap->video_isoc_streaming = 0; - } else { + if (isbad) + easycap_video_kill_urbs(peasycap); + else peasycap->video_isoc_streaming = 1; - JOM(4, "submitted %i video urbs\n", m); - } } else { JOM(4, "already streaming video urbs\n"); } return 0; } /*****************************************************************************/ -int kill_video_urbs(struct easycap *peasycap) +int easycap_audio_kill_urbs(struct easycap *peasycap) { int m; struct list_head *plist_head; struct data_urb *pdata_urb; - if (!peasycap) { - SAY("ERROR: peasycap is NULL\n"); + if (!peasycap->audio_isoc_streaming) + return 0; + + if (!peasycap->purb_audio_head) { + SAM("ERROR: peasycap->purb_audio_head is NULL\n"); return -EFAULT; } - if (!peasycap->video_isoc_streaming) { - JOM(8, "%i=video_isoc_streaming, no video urbs killed\n", - peasycap->video_isoc_streaming); - return 0; + + peasycap->audio_isoc_streaming = 0; + m = 0; + list_for_each(plist_head, peasycap->purb_audio_head) { + pdata_urb = list_entry(plist_head, struct data_urb, list_head); + if (pdata_urb && pdata_urb->purb) { + usb_kill_urb(pdata_urb->purb); + m++; + } } + + JOM(4, "%i audio urbs killed\n", m); + + return 0; +} +int easycap_video_kill_urbs(struct easycap *peasycap) +{ + int m; + struct list_head *plist_head; + struct data_urb *pdata_urb; + + if (!peasycap->video_isoc_streaming) + return 0; + if (!peasycap->purb_video_head) { SAM("ERROR: peasycap->purb_video_head is NULL\n"); return -EFAULT; @@ -694,8 +704,8 @@ static int videodev_release(struct video_device *pvideo_device) SAY("ending unsuccessfully\n"); return -EFAULT; } - if (0 != kill_video_urbs(peasycap)) { - SAM("ERROR: kill_video_urbs() failed\n"); + if (easycap_video_kill_urbs(peasycap)) { + SAM("ERROR: easycap_video_kill_urbs() failed\n"); return -EFAULT; } JOM(4, "ending successfully\n"); @@ -738,20 +748,15 @@ static void easycap_delete(struct kref *pkref) */ /*---------------------------------------------------------------------------*/ if (peasycap->purb_video_head) { - JOM(4, "freeing video urbs\n"); m = 0; - list_for_each(plist_head, (peasycap->purb_video_head)) { + list_for_each(plist_head, peasycap->purb_video_head) { pdata_urb = list_entry(plist_head, struct data_urb, list_head); - if (!pdata_urb) { - JOM(4, "ERROR: pdata_urb is NULL\n"); - } else { - if (pdata_urb->purb) { - usb_free_urb(pdata_urb->purb); - pdata_urb->purb = NULL; - peasycap->allocation_video_urb -= 1; - m++; - } + if (pdata_urb && pdata_urb->purb) { + usb_free_urb(pdata_urb->purb); + pdata_urb->purb = NULL; + peasycap->allocation_video_urb--; + m++; } } @@ -767,7 +772,6 @@ static void easycap_delete(struct kref *pkref) peasycap->allocation_video_struct -= sizeof(struct data_urb); kfree(pdata_urb); - pdata_urb = NULL; m++; } } @@ -832,15 +836,11 @@ static void easycap_delete(struct kref *pkref) list_for_each(plist_head, (peasycap->purb_audio_head)) { pdata_urb = list_entry(plist_head, struct data_urb, list_head); - if (!pdata_urb) - JOM(4, "ERROR: pdata_urb is NULL\n"); - else { - if (pdata_urb->purb) { - usb_free_urb(pdata_urb->purb); - pdata_urb->purb = NULL; - peasycap->allocation_audio_urb -= 1; - m++; - } + if (pdata_urb && pdata_urb->purb) { + usb_free_urb(pdata_urb->purb); + pdata_urb->purb = NULL; + peasycap->allocation_audio_urb--; + m++; } } JOM(4, "%i audio urbs freed\n", m); @@ -855,7 +855,6 @@ static void easycap_delete(struct kref *pkref) peasycap->allocation_audio_struct -= sizeof(struct data_urb); kfree(pdata_urb); - pdata_urb = NULL; m++; } } @@ -1084,7 +1083,7 @@ int easycap_dqbuf(struct easycap *peasycap, int mode) JOM(8, " ... failed returning -EIO\n"); peasycap->video_eof = 1; peasycap->audio_eof = 1; - kill_video_urbs(peasycap); + easycap_video_kill_urbs(peasycap); return -EIO; } peasycap->status = 0; @@ -1094,7 +1093,7 @@ int easycap_dqbuf(struct easycap *peasycap, int mode) #endif /*PERSEVERE*/ peasycap->video_eof = 1; peasycap->audio_eof = 1; - kill_video_urbs(peasycap); + easycap_video_kill_urbs(peasycap); JOM(8, "returning -EIO\n"); return -EIO; } @@ -1147,7 +1146,7 @@ int easycap_dqbuf(struct easycap *peasycap, int mode) JOM(8, " ... failed returning -EIO\n"); peasycap->video_eof = 1; peasycap->audio_eof = 1; - kill_video_urbs(peasycap); + easycap_video_kill_urbs(peasycap); return -EIO; } peasycap->status = 0; @@ -1157,7 +1156,7 @@ int easycap_dqbuf(struct easycap *peasycap, int mode) #endif /*PERSEVERE*/ peasycap->video_eof = 1; peasycap->audio_eof = 1; - kill_video_urbs(peasycap); + easycap_video_kill_urbs(peasycap); JOM(8, "returning -EIO\n"); return -EIO; } @@ -3969,12 +3968,9 @@ static void easycap_usb_disconnect(struct usb_interface *pusb_interface) { struct usb_host_interface *pusb_host_interface; struct usb_interface_descriptor *pusb_interface_descriptor; - u8 bInterfaceNumber; struct easycap *peasycap; - - struct list_head *plist_head; - struct data_urb *pdata_urb; - int minor, m, kd; + int minor, kd; + u8 bInterfaceNumber; JOT(4, "\n"); @@ -4009,45 +4005,14 @@ static void easycap_usb_disconnect(struct usb_interface *pusb_interface) peasycap->audio_eof = 1; wake_up_interruptible(&(peasycap->wq_video)); wake_up_interruptible(&(peasycap->wq_audio)); -/*---------------------------------------------------------------------------*/ + switch (bInterfaceNumber) { - case 0: { - if (peasycap->purb_video_head) { - JOM(4, "killing video urbs\n"); - m = 0; - list_for_each(plist_head, peasycap->purb_video_head) { - pdata_urb = list_entry(plist_head, - struct data_urb, list_head); - if (pdata_urb) { - if (pdata_urb->purb) { - usb_kill_urb(pdata_urb->purb); - m++; - } - } - } - JOM(4, "%i video urbs killed\n", m); - } + case 0: + easycap_video_kill_urbs(peasycap); break; - } -/*---------------------------------------------------------------------------*/ - case 2: { - if (peasycap->purb_audio_head) { - JOM(4, "killing audio urbs\n"); - m = 0; - list_for_each(plist_head, peasycap->purb_audio_head) { - pdata_urb = list_entry(plist_head, - struct data_urb, list_head); - if (pdata_urb) { - if (pdata_urb->purb) { - usb_kill_urb(pdata_urb->purb); - m++; - } - } - } - JOM(4, "%i audio urbs killed\n", m); - } + case 2: + easycap_audio_kill_urbs(peasycap); break; - } default: break; } diff --git a/drivers/staging/media/easycap/easycap_sound.c b/drivers/staging/media/easycap/easycap_sound.c index 70813a5..f7f9a76 100644 --- a/drivers/staging/media/easycap/easycap_sound.c +++ b/drivers/staging/media/easycap/easycap_sound.c @@ -138,18 +138,11 @@ static int submit_audio_urbs(struct easycap *peasycap) SAM("..... possibly inadequate USB bandwidth\n"); peasycap->audio_eof = 1; } - if (isbad) { - JOM(4, "attempting cleanup instead of submitting\n"); - list_for_each(plist_head, (peasycap->purb_audio_head)) { - pdata_urb = list_entry(plist_head, struct data_urb, list_head); - if (pdata_urb && pdata_urb->purb) - usb_kill_urb(pdata_urb->purb); - } - peasycap->audio_isoc_streaming = 0; - } else { + + if (isbad) + easycap_audio_kill_urbs(peasycap); + else peasycap->audio_isoc_streaming = m; - JOM(4, "submitted %i audio urbs\n", m); - } return 0; } -- cgit v0.10.2 From 4329f3c6a5fb4ed2332c7552894e7e4b8efef194 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Wed, 9 Nov 2011 08:26:38 -0300 Subject: [media] easycap: easycap_usb_driver should be static to easycap_main.c Signed-off-by: Tomas Winkler Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/staging/media/easycap/easycap.h b/drivers/staging/media/easycap/easycap.h index 1d98d31..9e9638c 100644 --- a/drivers/staging/media/easycap/easycap.h +++ b/drivers/staging/media/easycap/easycap.h @@ -567,7 +567,6 @@ extern bool easycap_readback; extern const struct easycap_standard easycap_standard[]; extern struct easycap_format easycap_format[]; extern struct v4l2_queryctrl easycap_control[]; -extern struct usb_driver easycap_usb_driver; extern struct easycap_dongle easycapdc60_dongle[]; #endif /* !__EASYCAP_H__ */ diff --git a/drivers/staging/media/easycap/easycap_main.c b/drivers/staging/media/easycap/easycap_main.c index c147c61..f7af1d2 100644 --- a/drivers/staging/media/easycap/easycap_main.c +++ b/drivers/staging/media/easycap/easycap_main.c @@ -4150,7 +4150,7 @@ static struct usb_device_id easycap_usb_device_id_table[] = { }; MODULE_DEVICE_TABLE(usb, easycap_usb_device_id_table); -struct usb_driver easycap_usb_driver = { +static struct usb_driver easycap_usb_driver = { .name = "easycap", .id_table = easycap_usb_device_id_table, .probe = easycap_usb_probe, -- cgit v0.10.2 From a5b6ee06b21eaee64f100be8591fd51917bdbe36 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Wed, 9 Nov 2011 08:26:39 -0300 Subject: [media] easycap: remove unused members of struct easycap Signed-off-by: Tomas Winkler Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/staging/media/easycap/easycap.h b/drivers/staging/media/easycap/easycap.h index 9e9638c..3a081ab 100644 --- a/drivers/staging/media/easycap/easycap.h +++ b/drivers/staging/media/easycap/easycap.h @@ -324,8 +324,6 @@ struct easycap { int lost[INPUT_MANY]; int merit[180]; - long long int dnbydt; - int video_interface; int video_altsetting_on; int video_altsetting_off; @@ -353,7 +351,6 @@ struct easycap { u8 *pcache; int video_mt; int audio_mt; - long long audio_bytes; u32 isequence; int vma_many; @@ -450,9 +447,6 @@ struct easycap { * SOUND PROPERTIES */ /*---------------------------------------------------------------------------*/ - - int audio_buffer_many; - int allocation_audio_urb; int allocation_audio_page; int allocation_audio_struct; -- cgit v0.10.2 From 96bec7dd72511e3c16588d9af52da2cc937f7ea1 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Wed, 9 Nov 2011 08:26:40 -0300 Subject: [media] easycap: add easycap prefix to global functions names Add easycap prefix to global function to reduce possibility of name collision. Signed-off-by: Tomas Winkler Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/staging/media/easycap/easycap.h b/drivers/staging/media/easycap/easycap.h index 3a081ab..b0e54f78 100644 --- a/drivers/staging/media/easycap/easycap.h +++ b/drivers/staging/media/easycap/easycap.h @@ -463,13 +463,16 @@ struct easycap { * VIDEO FUNCTION PROTOTYPES */ /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +int easycap_newinput(struct easycap *, int); +void easycap_testcard(struct easycap *, int); +int easycap_isdongle(struct easycap *); + long easycap_unlocked_ioctl(struct file *, unsigned int, unsigned long); -int easycap_dqbuf(struct easycap *, int); -int submit_video_urbs(struct easycap *); + +int easycap_video_dqbuf(struct easycap *, int); +int easycap_video_submit_urbs(struct easycap *); int easycap_video_kill_urbs(struct easycap *); -void easycap_testcard(struct easycap *, int); -int fillin_formats(void); -int newinput(struct easycap *, int); +int easycap_video_fillin_formats(void); int adjust_standard(struct easycap *, v4l2_std_id); int adjust_format(struct easycap *, u32, u32, u32, int, bool); @@ -485,15 +488,15 @@ int adjust_hue(struct easycap *, int); int easycap_alsa_probe(struct easycap *); int easycap_audio_kill_urbs(struct easycap *); void easycap_alsa_complete(struct urb *); -int audio_setup(struct easycap *); /*---------------------------------------------------------------------------*/ /* * LOW-LEVEL FUNCTION PROTOTYPES */ /*---------------------------------------------------------------------------*/ -int audio_gainset(struct usb_device *, s8); +int easycap_audio_gainset(struct usb_device *, s8); +int easycap_audio_setup(struct easycap *); -int wakeup_device(struct usb_device *); +int easycap_wakeup_device(struct usb_device *); int setup_stk(struct usb_device *, bool); int setup_saa(struct usb_device *, bool); @@ -507,7 +510,6 @@ int read_saa(struct usb_device *, u16); int write_saa(struct usb_device *, u16, u16); int start_100(struct usb_device *); int stop_100(struct usb_device *); -int isdongle(struct easycap *); /*---------------------------------------------------------------------------*/ diff --git a/drivers/staging/media/easycap/easycap_ioctl.c b/drivers/staging/media/easycap/easycap_ioctl.c index 90d4384..9413b37 100644 --- a/drivers/staging/media/easycap/easycap_ioctl.c +++ b/drivers/staging/media/easycap/easycap_ioctl.c @@ -330,7 +330,7 @@ int adjust_standard(struct easycap *peasycap, v4l2_std_id std_id) "from 0x%02X to 0x%02X\n", reg, itwas, isnow); } if (resubmit) - submit_video_urbs(peasycap); + easycap_video_submit_urbs(peasycap); return 0; } /*****************************************************************************/ @@ -621,7 +621,7 @@ int adjust_format(struct easycap *peasycap, } /*---------------------------------------------------------------------------*/ if (resubmit) - submit_video_urbs(peasycap); + easycap_video_submit_urbs(peasycap); return peasycap_best_format - easycap_format; } @@ -879,7 +879,7 @@ static int adjust_volume(struct easycap *peasycap, int value) mood = (16 > peasycap->volume) ? 16 : ((31 < peasycap->volume) ? 31 : (s8) peasycap->volume); - if (!audio_gainset(peasycap->pusb_device, mood)) { + if (!easycap_audio_gainset(peasycap->pusb_device, mood)) { SAM("WARNING: failed to adjust volume to " "0x%2X\n", mood); return -ENOENT; @@ -963,7 +963,7 @@ long easycap_unlocked_ioctl(struct file *file, SAM("ERROR: peasycap->pusb_device is NULL\n"); return -EFAULT; } - kd = isdongle(peasycap); + kd = easycap_isdongle(peasycap); if (0 <= kd && DONGLE_MANY > kd) { if (mutex_lock_interruptible(&easycapdc60_dongle[kd].mutex_video)) { SAY("ERROR: cannot lock " @@ -978,7 +978,7 @@ long easycap_unlocked_ioctl(struct file *file, * IF NECESSARY, BAIL OUT. */ /*---------------------------------------------------------------------------*/ - if (kd != isdongle(peasycap)) + if (kd != easycap_isdongle(peasycap)) return -ERESTARTSYS; if (!file) { SAY("ERROR: file is NULL\n"); @@ -1218,7 +1218,7 @@ long easycap_unlocked_ioctl(struct file *file, return -EINVAL; } - rc = newinput(peasycap, (int)index); + rc = easycap_newinput(peasycap, (int)index); if (0 == rc) { JOM(8, "newinput(.,%i) OK\n", (int)index); } else { @@ -2201,7 +2201,7 @@ long easycap_unlocked_ioctl(struct file *file, if (!peasycap->polled) { do { - rcdq = easycap_dqbuf(peasycap, 0); + rcdq = easycap_video_dqbuf(peasycap, 0); if (-EIO == rcdq) { JOM(8, "returning -EIO because " "dqbuf() returned -EIO\n"); @@ -2305,7 +2305,7 @@ long easycap_unlocked_ioctl(struct file *file, mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EFAULT; } - submit_video_urbs(peasycap); + easycap_video_submit_urbs(peasycap); peasycap->video_idle = 0; peasycap->audio_idle = 0; peasycap->video_eof = 0; diff --git a/drivers/staging/media/easycap/easycap_low.c b/drivers/staging/media/easycap/easycap_low.c index 212830b..59fdb8f 100644 --- a/drivers/staging/media/easycap/easycap_low.c +++ b/drivers/staging/media/easycap/easycap_low.c @@ -724,10 +724,11 @@ int stop_100(struct usb_device *p) /****************************************************************************/ /****************************************************************************/ /*****************************************************************************/ -int wakeup_device(struct usb_device *pusb_device) +int easycap_wakeup_device(struct usb_device *pusb_device) { if (!pusb_device) return -ENODEV; + return usb_control_msg(pusb_device, usb_sndctrlpipe(pusb_device, 0), USB_REQ_SET_FEATURE, USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE, @@ -735,8 +736,7 @@ int wakeup_device(struct usb_device *pusb_device) 0, NULL, 0, 50000); } /*****************************************************************************/ -int -audio_setup(struct easycap *peasycap) +int easycap_audio_setup(struct easycap *peasycap) { struct usb_device *pusb_device; u8 buffer[1]; @@ -817,7 +817,7 @@ audio_setup(struct easycap *peasycap) * SELECT AUDIO SOURCE "LINE IN" AND SET THE AUDIO GAIN. */ /*---------------------------------------------------------------------------*/ - if (0 != audio_gainset(pusb_device, peasycap->gain)) + if (easycap_audio_gainset(pusb_device, peasycap->gain)) SAY("ERROR: audio_gainset() failed\n"); check_vt(pusb_device); return 0; @@ -894,7 +894,7 @@ int check_vt(struct usb_device *pusb_device) * 31 12.0 22.5 34.5 */ /*---------------------------------------------------------------------------*/ -int audio_gainset(struct usb_device *pusb_device, s8 loud) +int easycap_audio_gainset(struct usb_device *pusb_device, s8 loud) { int igot; u8 tmp; diff --git a/drivers/staging/media/easycap/easycap_main.c b/drivers/staging/media/easycap/easycap_main.c index f7af1d2..ce23beb 100644 --- a/drivers/staging/media/easycap/easycap_main.c +++ b/drivers/staging/media/easycap/easycap_main.c @@ -129,7 +129,7 @@ const char *strerror(int err) * THIS ROUTINE DOES NOT DETECT DUPLICATE OCCURRENCES OF POINTER peasycap */ /*---------------------------------------------------------------------------*/ -int isdongle(struct easycap *peasycap) +int easycap_isdongle(struct easycap *peasycap) { int k; if (!peasycap) @@ -170,7 +170,7 @@ static int easycap_open(struct inode *inode, struct file *file) JOM(16, "peasycap->pusb_device=%p\n", peasycap->pusb_device); file->private_data = peasycap; - rc = wakeup_device(peasycap->pusb_device); + rc = easycap_wakeup_device(peasycap->pusb_device); if (rc) { SAM("ERROR: wakeup_device() rc = %i\n", rc); if (-ENODEV == rc) @@ -307,7 +307,7 @@ static int reset(struct easycap *peasycap) peasycap->saturation = -8192; peasycap->hue = -8192; - rc = newinput(peasycap, input); + rc = easycap_newinput(peasycap, input); if (rc) { SAM("ERROR: newinput(.,%i) rc = %i\n", rc, input); @@ -368,8 +368,7 @@ static int reset(struct easycap *peasycap) * SO IT SHOULD WRITE ONLY SPARINGLY TO THE LOGFILE. */ /*---------------------------------------------------------------------------*/ -int -newinput(struct easycap *peasycap, int input) +int easycap_newinput(struct easycap *peasycap, int input) { int rc, k, m, mood, off; int inputnow, video_idlenow, audio_idlenow; @@ -536,7 +535,7 @@ newinput(struct easycap *peasycap, int input) return -EFAULT; } if (resubmit) - submit_video_urbs(peasycap); + easycap_video_submit_urbs(peasycap); peasycap->video_isoc_sequence = VIDEO_ISOC_BUFFER_MANY - 1; peasycap->video_idle = video_idlenow; @@ -546,7 +545,7 @@ newinput(struct easycap *peasycap, int input) return 0; } /*****************************************************************************/ -int submit_video_urbs(struct easycap *peasycap) +int easycap_video_submit_urbs(struct easycap *peasycap) { struct data_urb *pdata_urb; struct urb *purb; @@ -741,7 +740,7 @@ static void easycap_delete(struct kref *pkref) SAM("ERROR: peasycap is NULL: cannot perform deletions\n"); return; } - kd = isdongle(peasycap); + kd = easycap_isdongle(peasycap); /*---------------------------------------------------------------------------*/ /* * FREE VIDEO. @@ -943,7 +942,7 @@ static unsigned int easycap_poll(struct file *file, poll_table *wait) return -EFAULT; } /*---------------------------------------------------------------------------*/ - kd = isdongle(peasycap); + kd = easycap_isdongle(peasycap); if (0 <= kd && DONGLE_MANY > kd) { if (mutex_lock_interruptible(&easycapdc60_dongle[kd].mutex_video)) { SAY("ERROR: cannot down dongle[%i].mutex_video\n", kd); @@ -955,7 +954,7 @@ static unsigned int easycap_poll(struct file *file, poll_table *wait) * peasycap, IN WHICH CASE A REPEAT CALL TO isdongle() WILL FAIL. * IF NECESSARY, BAIL OUT. */ - if (kd != isdongle(peasycap)) { + if (kd != easycap_isdongle(peasycap)) { mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -ERESTARTSYS; } @@ -983,7 +982,7 @@ static unsigned int easycap_poll(struct file *file, poll_table *wait) */ return -ERESTARTSYS; /*---------------------------------------------------------------------------*/ - rc = easycap_dqbuf(peasycap, 0); + rc = easycap_video_dqbuf(peasycap, 0); peasycap->polled = 1; mutex_unlock(&easycapdc60_dongle[kd].mutex_video); if (rc) @@ -997,7 +996,7 @@ static unsigned int easycap_poll(struct file *file, poll_table *wait) * IF mode IS NONZERO THIS ROUTINE RETURNS -EAGAIN RATHER THAN BLOCKING. */ /*---------------------------------------------------------------------------*/ -int easycap_dqbuf(struct easycap *peasycap, int mode) +int easycap_video_dqbuf(struct easycap *peasycap, int mode) { int input, ifield, miss, rc; @@ -3036,7 +3035,7 @@ static int easycap_usb_probe(struct usb_interface *intf, * DYNAMICALLY FILL IN THE AVAILABLE FORMATS ... */ /*---------------------------------------------------------------------------*/ - rc = fillin_formats(); + rc = easycap_video_fillin_formats(); if (0 > rc) { SAM("ERROR: fillin_formats() rc = %i\n", rc); return -EFAULT; @@ -4025,7 +4024,7 @@ static void easycap_usb_disconnect(struct usb_interface *pusb_interface) * AN EasyCAP IS UNPLUGGED WHILE THE URBS ARE RUNNING. BEWARE. */ /*--------------------------------------------------------------------------*/ - kd = isdongle(peasycap); + kd = easycap_isdongle(peasycap); switch (bInterfaceNumber) { case 0: { if (0 <= kd && DONGLE_MANY > kd) { diff --git a/drivers/staging/media/easycap/easycap_settings.c b/drivers/staging/media/easycap/easycap_settings.c index 70f59b1..3f5f5b3 100644 --- a/drivers/staging/media/easycap/easycap_settings.c +++ b/drivers/staging/media/easycap/easycap_settings.c @@ -313,7 +313,7 @@ const struct easycap_standard easycap_standard[] = { struct easycap_format easycap_format[1 + SETTINGS_MANY]; -int fillin_formats(void) +int easycap_video_fillin_formats(void) { const char *name1, *name2, *name3, *name4; struct v4l2_format *fmt; diff --git a/drivers/staging/media/easycap/easycap_sound.c b/drivers/staging/media/easycap/easycap_sound.c index f7f9a76..353b6b7 100644 --- a/drivers/staging/media/easycap/easycap_sound.c +++ b/drivers/staging/media/easycap/easycap_sound.c @@ -61,7 +61,7 @@ static const struct snd_pcm_hardware alsa_hardware = { * SUBMIT ALL AUDIO URBS. */ /*---------------------------------------------------------------------------*/ -static int submit_audio_urbs(struct easycap *peasycap) +static int easycap_audio_submit_urbs(struct easycap *peasycap) { struct data_urb *pdata_urb; struct urb *purb; @@ -69,10 +69,6 @@ static int submit_audio_urbs(struct easycap *peasycap) int j, isbad, nospc, m, rc; int isbuf; - if (!peasycap) { - SAY("ERROR: peasycap is NULL\n"); - return -EFAULT; - } if (!peasycap->purb_audio_head) { SAM("ERROR: peasycap->urb_audio_head uninitialized\n"); return -EFAULT; @@ -167,7 +163,7 @@ static int easycap_sound_setup(struct easycap *peasycap) } JOM(16, "0x%08lX=peasycap->pusb_device\n", (long int)peasycap->pusb_device); - rc = audio_setup(peasycap); + rc = easycap_audio_setup(peasycap); JOM(8, "audio_setup() returned %i\n", rc); if (!peasycap->pusb_device) { @@ -184,13 +180,13 @@ static int easycap_sound_setup(struct easycap *peasycap) JOM(8, "usb_set_interface(.,%i,%i) returned %i\n", peasycap->audio_interface, peasycap->audio_altsetting_on, rc); - rc = wakeup_device(peasycap->pusb_device); + rc = easycap_wakeup_device(peasycap->pusb_device); JOM(8, "wakeup_device() returned %i\n", rc); peasycap->audio_eof = 0; peasycap->audio_idle = 0; - submit_audio_urbs(peasycap); + easycap_audio_submit_urbs(peasycap); JOM(4, "finished initialization\n"); return 0; @@ -203,8 +199,7 @@ static int easycap_sound_setup(struct easycap *peasycap) * IT IS RESUBMITTED PROVIDED peasycap->audio_isoc_streaming IS NOT ZERO. */ /*---------------------------------------------------------------------------*/ -void -easycap_alsa_complete(struct urb *purb) +void easycap_alsa_complete(struct urb *purb) { struct easycap *peasycap; struct snd_pcm_substream *pss; -- cgit v0.10.2 From 0b217d2125acc039d2f3a94f01821472fbbb75b6 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Wed, 9 Nov 2011 08:26:41 -0300 Subject: [media] easycap: drop usb_class_driver Drop usb_class_driver and collaterals as it is not used Signed-off-by: Tomas Winkler Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/staging/media/easycap/easycap.h b/drivers/staging/media/easycap/easycap.h index b0e54f78..a007e74 100644 --- a/drivers/staging/media/easycap/easycap.h +++ b/drivers/staging/media/easycap/easycap.h @@ -98,7 +98,6 @@ #define EASYCAP_DRIVER_VERSION "0.9.01" #define EASYCAP_DRIVER_DESCRIPTION "easycapdc60" -#define USB_SKEL_MINOR_BASE 192 #define DONGLE_MANY 8 #define INPUT_MANY 6 /*---------------------------------------------------------------------------*/ diff --git a/drivers/staging/media/easycap/easycap_main.c b/drivers/staging/media/easycap/easycap_main.c index ce23beb..525a6b6 100644 --- a/drivers/staging/media/easycap/easycap_main.c +++ b/drivers/staging/media/easycap/easycap_main.c @@ -113,16 +113,6 @@ const char *strerror(int err) #undef ERRNOSTR } -/*---------------------------------------------------------------------------*/ -/* - * PARAMETERS USED WHEN REGISTERING THE VIDEO INTERFACE - * - * NOTE: SOME KERNELS IGNORE usb_class_driver.minor_base, AS MENTIONED BY - * CORBET ET AL. "LINUX DEVICE DRIVERS", 3rd EDITION, PAGE 253. - * THIS IS THE CASE FOR OpenSUSE. - */ -/*---------------------------------------------------------------------------*/ -/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ /****************************************************************************/ /*---------------------------------------------------------------------------*/ /* @@ -2856,20 +2846,7 @@ static void easycap_complete(struct urb *purb) } return; } -static const struct file_operations easycap_fops = { - .owner = THIS_MODULE, - .open = easycap_open, - .unlocked_ioctl = easycap_unlocked_ioctl, - .poll = easycap_poll, - .mmap = easycap_mmap, - .llseek = no_llseek, -}; -static const struct usb_class_driver easycap_class = { - .name = "usb/easycap%d", - .fops = &easycap_fops, - .minor_base = USB_SKEL_MINOR_BASE, -}; -/*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ + static const struct v4l2_file_operations v4l2_fops = { .owner = THIS_MODULE, .open = easycap_open_noinode, -- cgit v0.10.2 From a6ff0a06d8634a07db52dbc006fd9ce4c438c1e3 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Wed, 9 Nov 2011 08:26:42 -0300 Subject: [media] easycap: fix warnings: variable set but not used Signed-off-by: Tomas Winkler Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/staging/media/easycap/easycap_low.c b/drivers/staging/media/easycap/easycap_low.c index 59fdb8f..0380bab 100644 --- a/drivers/staging/media/easycap/easycap_low.c +++ b/drivers/staging/media/easycap/easycap_low.c @@ -468,13 +468,17 @@ int setup_stk(struct usb_device *p, bool ntsc) /****************************************************************************/ int setup_saa(struct usb_device *p, bool ntsc) { - int i, ir; + int i, rc; const struct saa7113config *cfg; if (!p) return -ENODEV; cfg = (ntsc) ? saa7113configNTSC : saa7113configPAL; - for (i = 0; cfg[i].reg != 0xFF; i++) - ir = write_saa(p, cfg[i].reg, cfg[i].set); + for (i = 0; cfg[i].reg != 0xFF; i++) { + rc = write_saa(p, cfg[i].reg, cfg[i].set); + if (rc) + dev_err(&p->dev, + "Failed to set SAA register %d", cfg[i].reg); + } return 0; } /****************************************************************************/ diff --git a/drivers/staging/media/easycap/easycap_main.c b/drivers/staging/media/easycap/easycap_main.c index 525a6b6..8ff5f38 100644 --- a/drivers/staging/media/easycap/easycap_main.c +++ b/drivers/staging/media/easycap/easycap_main.c @@ -1199,8 +1199,6 @@ int easycap_video_dqbuf(struct easycap *peasycap, int mode) * WHEN BOOLEAN PARAMETER decimatepixel IS true, ONLY THE FIELD FOR WHICH * odd==false IS TRANSFERRED TO THE FRAME BUFFER. * - * THE BOOLEAN PARAMETER offerfields IS true ONLY WHEN THE USER PROGRAM - * CHOOSES THE OPTION V4L2_FIELD_INTERLACED. */ /*---------------------------------------------------------------------------*/ static int field2frame(struct easycap *peasycap) @@ -1212,7 +1210,7 @@ static int field2frame(struct easycap *peasycap) int rc, bytesperpixel, multiplier; int much, more, over, rump, caches, input; u8 mask, margin; - bool odd, isuy, decimatepixel, offerfields, badinput; + bool odd, isuy, decimatepixel, badinput; if (!peasycap) { SAY("ERROR: peasycap is NULL\n"); @@ -1228,8 +1226,6 @@ static int field2frame(struct easycap *peasycap) peasycap->field_buffer[peasycap->field_read][0].input, peasycap->field_read, peasycap->frame_fill); JOM(8, "===== %i=bytesperpixel\n", peasycap->bytesperpixel); - if (peasycap->offerfields) - JOM(8, "===== offerfields\n"); /*---------------------------------------------------------------------------*/ /* @@ -1251,7 +1247,6 @@ static int field2frame(struct easycap *peasycap) #endif /*EASYCAP_TESTCARD*/ /*---------------------------------------------------------------------------*/ - offerfields = peasycap->offerfields; bytesperpixel = peasycap->bytesperpixel; decimatepixel = peasycap->decimatepixel; diff --git a/drivers/staging/media/easycap/easycap_sound.c b/drivers/staging/media/easycap/easycap_sound.c index 353b6b7..8c8bcae 100644 --- a/drivers/staging/media/easycap/easycap_sound.c +++ b/drivers/staging/media/easycap/easycap_sound.c @@ -592,7 +592,6 @@ static int easycap_alsa_ack(struct snd_pcm_substream *pss) static int easycap_alsa_trigger(struct snd_pcm_substream *pss, int cmd) { struct easycap *peasycap; - int retval; JOT(4, "%i=cmd cf %i=START %i=STOP\n", cmd, SNDRV_PCM_TRIGGER_START, SNDRV_PCM_TRIGGER_STOP); @@ -615,7 +614,7 @@ static int easycap_alsa_trigger(struct snd_pcm_substream *pss, int cmd) break; } default: - retval = -EINVAL; + return -EINVAL; } return 0; } -- cgit v0.10.2 From a1ed02e9f1a0fa34e5b5e978209204033bb9cf4f Mon Sep 17 00:00:00 2001 From: Andreas Oberritter Date: Wed, 16 Nov 2011 11:06:50 -0300 Subject: [media] em28xx: Add Terratec Cinergy HTC Stick Signed-off-by: Andreas Oberritter Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c index 5b0336b..1704da0 100644 --- a/drivers/media/video/em28xx/em28xx-cards.c +++ b/drivers/media/video/em28xx/em28xx-cards.c @@ -927,6 +927,19 @@ struct em28xx_board em28xx_boards[] = { EM28XX_I2C_CLK_WAIT_ENABLE | EM28XX_I2C_FREQ_400_KHZ, }, + [EM2884_BOARD_CINERGY_HTC_STICK] = { + .name = "Terratec Cinergy HTC Stick", + .has_dvb = 1, +#if 0 + .tuner_type = TUNER_PHILIPS_TDA8290, + .tuner_addr = 0x41, + .dvb_gpio = terratec_h5_digital, /* FIXME: probably wrong */ + .tuner_gpio = terratec_h5_gpio, +#endif + .i2c_speed = EM2874_I2C_SECONDARY_BUS_SELECT | + EM28XX_I2C_CLK_WAIT_ENABLE | + EM28XX_I2C_FREQ_400_KHZ, + }, [EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900] = { .name = "Hauppauge WinTV HVR 900", .tda9887_conf = TDA9887_PRESENT, @@ -1960,6 +1973,8 @@ struct usb_device_id em28xx_id_table[] = { .driver_info = EM2860_BOARD_TERRATEC_GRABBY }, { USB_DEVICE(0x0ccd, 0x10AF), .driver_info = EM2860_BOARD_TERRATEC_GRABBY }, + { USB_DEVICE(0x0ccd, 0x00b2), + .driver_info = EM2884_BOARD_CINERGY_HTC_STICK }, { USB_DEVICE(0x0fd9, 0x0033), .driver_info = EM2860_BOARD_ELGATO_VIDEO_CAPTURE}, { USB_DEVICE(0x185b, 0x2870), diff --git a/drivers/media/video/em28xx/em28xx-dvb.c b/drivers/media/video/em28xx/em28xx-dvb.c index eb41e25..7f0592c 100644 --- a/drivers/media/video/em28xx/em28xx-dvb.c +++ b/drivers/media/video/em28xx/em28xx-dvb.c @@ -902,6 +902,7 @@ static int em28xx_dvb_init(struct em28xx *dev) break; } case EM2884_BOARD_TERRATEC_H5: + case EM2884_BOARD_CINERGY_HTC_STICK: terratec_h5_init(dev); dvb->dont_attach_fe1 = 1; diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h index c16ae8f..b1199ef 100644 --- a/drivers/media/video/em28xx/em28xx.h +++ b/drivers/media/video/em28xx/em28xx.h @@ -123,6 +123,7 @@ #define EM2884_BOARD_TERRATEC_H5 79 #define EM28174_BOARD_PCTV_460E 80 #define EM2884_BOARD_HAUPPAUGE_WINTV_HVR_930C 81 +#define EM2884_BOARD_CINERGY_HTC_STICK 82 /* Limits minimum and default number of buffers */ #define EM28XX_MIN_BUF 4 -- cgit v0.10.2 From dd7aaa4d9d97a8571bcfa498e90b9daf540db1cf Mon Sep 17 00:00:00 2001 From: Gianluca Gennari Date: Thu, 17 Nov 2011 12:35:05 -0300 Subject: [media] staging: as102: Add support for Sky Italia Digital Key based on the same chip Add support for the Sky Italia Digital Key, an USB dongle offered by Sky Italia to its customers for use with their satellite set-top-boxes. This is the "green led" model based on the Abilis as102 chip, while the so called "blue led" model is based on the Avermedia A867 design. Cc: Devin Heitmueller Signed-off-by: Sylwester Nawrocki Signed-off-by: Gianluca Gennari Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/staging/media/as102/as102_usb_drv.c b/drivers/staging/media/as102/as102_usb_drv.c index 9faab5b..7bcb28c 100644 --- a/drivers/staging/media/as102/as102_usb_drv.c +++ b/drivers/staging/media/as102/as102_usb_drv.c @@ -42,6 +42,7 @@ static struct usb_device_id as102_usb_id_table[] = { { USB_DEVICE(PCTV_74E_USB_VID, PCTV_74E_USB_PID) }, { USB_DEVICE(ELGATO_EYETV_DTT_USB_VID, ELGATO_EYETV_DTT_USB_PID) }, { USB_DEVICE(NBOX_DVBT_DONGLE_USB_VID, NBOX_DVBT_DONGLE_USB_PID) }, + { USB_DEVICE(SKY_IT_DIGITAL_KEY_USB_VID, SKY_IT_DIGITAL_KEY_USB_PID) }, { } /* Terminating entry */ }; @@ -52,6 +53,7 @@ static const char * const as102_device_names[] = { AS102_PCTV_74E, AS102_ELGATO_EYETV_DTT_NAME, AS102_NBOX_DVBT_DONGLE_NAME, + AS102_SKY_IT_DIGITAL_KEY_NAME, NULL /* Terminating entry */ }; diff --git a/drivers/staging/media/as102/as102_usb_drv.h b/drivers/staging/media/as102/as102_usb_drv.h index 35925b7..fc2884a 100644 --- a/drivers/staging/media/as102/as102_usb_drv.h +++ b/drivers/staging/media/as102/as102_usb_drv.h @@ -47,6 +47,11 @@ #define NBOX_DVBT_DONGLE_USB_VID 0x0b89 #define NBOX_DVBT_DONGLE_USB_PID 0x0007 +/* Sky Italia: Digital Key (green led) */ +#define AS102_SKY_IT_DIGITAL_KEY_NAME "Sky IT Digital Key (green led)" +#define SKY_IT_DIGITAL_KEY_USB_VID 0x2137 +#define SKY_IT_DIGITAL_KEY_USB_PID 0x0001 + void as102_urb_stream_irq(struct urb *urb); struct as10x_usb_token_cmd_t { -- cgit v0.10.2 From 2e802861403c95ad6a566ff6d7a1a1a45d29c30e Mon Sep 17 00:00:00 2001 From: Olivier Grenie Date: Fri, 5 Aug 2011 10:39:15 -0300 Subject: [media] dib7000p/dib0090: update the driver This patch intends to update the dib7000p and dib0090 driver in order to improve the performances. Signed-off-by: Olivier Grenie Signed-off-by: Patrick Boettcher Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/dvb/dvb-usb/dib0700_devices.c b/drivers/media/dvb/dvb-usb/dib0700_devices.c index f313182..771dfda 100644 --- a/drivers/media/dvb/dvb-usb/dib0700_devices.c +++ b/drivers/media/dvb/dvb-usb/dib0700_devices.c @@ -2092,6 +2092,14 @@ static int dib7090_agc_startup(struct dvb_frontend *fe, struct dvb_frontend_para return 0; } +static int dib7090_agc_restart(struct dvb_frontend *fe, u8 restart) +{ + deb_info("AGC restart callback: %d", restart); + if (restart == 0) /* before AGC startup */ + dib0090_set_dc_servo(fe, 1); + return 0; +} + static struct dib0090_wbd_slope dib7090_wbd_table[] = { { 380, 81, 850, 64, 540, 4}, { 860, 51, 866, 21, 375, 4}, diff --git a/drivers/media/dvb/frontends/dib0090.c b/drivers/media/dvb/frontends/dib0090.c index b174d1c..9030f3d 100644 --- a/drivers/media/dvb/frontends/dib0090.c +++ b/drivers/media/dvb/frontends/dib0090.c @@ -1112,13 +1112,21 @@ void dib0090_pwm_gain_reset(struct dvb_frontend *fe) else dib0090_write_reg(state, 0x32, (0 << 11)); - dib0090_write_reg(state, 0x04, 0x01); + dib0090_write_reg(state, 0x04, 0x03); dib0090_write_reg(state, 0x39, (1 << 10)); } } EXPORT_SYMBOL(dib0090_pwm_gain_reset); +void dib0090_set_dc_servo(struct dvb_frontend *fe, u8 DC_servo_cutoff) +{ + struct dib0090_state *state = fe->tuner_priv; + if (DC_servo_cutoff < 4) + dib0090_write_reg(state, 0x04, DC_servo_cutoff); +} +EXPORT_SYMBOL(dib0090_set_dc_servo); + static u32 dib0090_get_slow_adc_val(struct dib0090_state *state) { u16 adc_val = dib0090_read_reg(state, 0x1d); @@ -1505,7 +1513,10 @@ static int dib0090_reset(struct dvb_frontend *fe) dib0090_set_EFUSE(state); /* Congigure in function of the crystal */ - if (state->config->io.clock_khz >= 24000) + if (state->config->force_crystal_mode != 0) + dib0090_write_reg(state, 0x14, + state->config->force_crystal_mode & 3); + else if (state->config->io.clock_khz >= 24000) dib0090_write_reg(state, 0x14, 1); else dib0090_write_reg(state, 0x14, 2); diff --git a/drivers/media/dvb/frontends/dib0090.h b/drivers/media/dvb/frontends/dib0090.h index 13d8524..648318a 100644 --- a/drivers/media/dvb/frontends/dib0090.h +++ b/drivers/media/dvb/frontends/dib0090.h @@ -71,6 +71,8 @@ struct dib0090_config { u8 fref_clock_ratio; u16 force_cband_input; struct dib0090_wbd_slope *wbd; + u8 is_dib7090e; + u8 force_crystal_mode; }; #if defined(CONFIG_DVB_TUNER_DIB0090) || (defined(CONFIG_DVB_TUNER_DIB0090_MODULE) && defined(MODULE)) @@ -83,6 +85,7 @@ extern int dib0090_gain_control(struct dvb_frontend *fe); extern enum frontend_tune_state dib0090_get_tune_state(struct dvb_frontend *fe); extern int dib0090_set_tune_state(struct dvb_frontend *fe, enum frontend_tune_state tune_state); extern void dib0090_get_current_gain(struct dvb_frontend *fe, u16 * rf, u16 * bb, u16 * rf_gain_limit, u16 * rflt); +extern void dib0090_set_dc_servo(struct dvb_frontend *fe, u8 DC_servo_cutoff); #else static inline struct dvb_frontend *dib0090_register(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct dib0090_config *config) { @@ -134,6 +137,11 @@ static inline void dib0090_get_current_gain(struct dvb_frontend *fe, u16 * rf, u { printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); } + +static inline void dib0090_set_dc_servo(struct dvb_frontend *fe, u8 DC_servo_cutoff) +{ + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); +} #endif #endif diff --git a/drivers/media/dvb/frontends/dib7000p.c b/drivers/media/dvb/frontends/dib7000p.c index ce8534f..08e62a4 100644 --- a/drivers/media/dvb/frontends/dib7000p.c +++ b/drivers/media/dvb/frontends/dib7000p.c @@ -70,6 +70,8 @@ struct dib7000p_state { u8 i2c_write_buffer[4]; u8 i2c_read_buffer[2]; struct mutex i2c_buffer_lock; + + u8 input_mode_mpeg; }; enum dib7000p_power_mode { @@ -78,8 +80,18 @@ enum dib7000p_power_mode { DIB7000P_POWER_INTERFACE_ONLY, }; +/* dib7090 specific fonctions */ +#define MPEG_ON_DIBTX 1 +#define DIV_ON_DIBTX 2 +#define ADC_ON_DIBTX 3 +#define DEMOUT_ON_HOSTBUS 4 +#define DIBTX_ON_HOSTBUS 5 +#define MPEG_ON_HOSTBUS 6 + static int dib7090_set_output_mode(struct dvb_frontend *fe, int mode); static int dib7090_set_diversity_in(struct dvb_frontend *fe, int onoff); +static void dib7090_setDibTxMux(struct dib7000p_state *state, int mode); +static void dib7090_setHostBusMux(struct dib7000p_state *state, int mode); static u16 dib7000p_read_word(struct dib7000p_state *state, u16 reg) { @@ -276,17 +288,23 @@ static int dib7000p_set_power_mode(struct dib7000p_state *state, enum dib7000p_p dib7000p_write_word(state, 774, reg_774); dib7000p_write_word(state, 775, reg_775); dib7000p_write_word(state, 776, reg_776); - dib7000p_write_word(state, 899, reg_899); dib7000p_write_word(state, 1280, reg_1280); + if (state->version != SOC7090) + dib7000p_write_word(state, 899, reg_899); return 0; } static void dib7000p_set_adc_state(struct dib7000p_state *state, enum dibx000_adc_states no) { - u16 reg_908 = dib7000p_read_word(state, 908), reg_909 = dib7000p_read_word(state, 909); + u16 reg_908 = 0, reg_909 = 0; u16 reg; + if (state->version != SOC7090) { + reg_908 = dib7000p_read_word(state, 908); + reg_909 = dib7000p_read_word(state, 909); + } + switch (no) { case DIBX000_SLOW_ADC_ON: if (state->version == SOC7090) { @@ -342,8 +360,10 @@ static void dib7000p_set_adc_state(struct dib7000p_state *state, enum dibx000_ad reg_909 |= (state->cfg.disable_sample_and_hold & 1) << 4; reg_908 |= (state->cfg.enable_current_mirror & 1) << 7; - dib7000p_write_word(state, 908, reg_908); - dib7000p_write_word(state, 909, reg_909); + if (state->version != SOC7090) { + dib7000p_write_word(state, 908, reg_908); + dib7000p_write_word(state, 909, reg_909); + } } static int dib7000p_set_bandwidth(struct dib7000p_state *state, u32 bw) @@ -519,7 +539,7 @@ static u16 dib7000p_defaults[] = { // auto search configuration 3, 2, 0x0004, - 0x1000, + (1<<3)|(1<<11)|(1<<12)|(1<<13), 0x0814, /* Equal Lock */ 12, 6, @@ -595,13 +615,6 @@ static u16 dib7000p_defaults[] = { 1, 235, 0x0062, - 2, 901, - 0x0006, - (3 << 10) | (1 << 6), - - 1, 905, - 0x2c8e, - 0, }; @@ -618,15 +631,18 @@ static int dib7000p_demod_reset(struct dib7000p_state *state) dib7000p_write_word(state, 770, 0xffff); dib7000p_write_word(state, 771, 0xffff); dib7000p_write_word(state, 772, 0x001f); - dib7000p_write_word(state, 898, 0x0003); dib7000p_write_word(state, 1280, 0x001f - ((1 << 4) | (1 << 3))); dib7000p_write_word(state, 770, 0); dib7000p_write_word(state, 771, 0); dib7000p_write_word(state, 772, 0); - dib7000p_write_word(state, 898, 0); dib7000p_write_word(state, 1280, 0); + if (state->version != SOC7090) { + dib7000p_write_word(state, 898, 0x0003); + dib7000p_write_word(state, 898, 0); + } + /* default */ dib7000p_reset_pll(state); @@ -640,7 +656,7 @@ static int dib7000p_demod_reset(struct dib7000p_state *state) dib7000p_write_word(state, 42, (1<<5) | 3); /* P_iqc_thsat_ipc = 1 ; P_iqc_win2 = 3 */ dib7000p_write_word(state, 43, 0x2d4); /*-300 fag P_iqc_dect_min = -280 */ dib7000p_write_word(state, 44, 300); /* 300 fag P_iqc_dect_min = +280 */ - dib7000p_write_word(state, 273, (1<<6) | 30); + dib7000p_write_word(state, 273, (0<<6) | 30); } if (dib7000p_set_output_mode(state, OUTMODE_HIGH_Z) != 0) dprintk("OUTPUT_MODE could not be reset."); @@ -655,7 +671,7 @@ static int dib7000p_demod_reset(struct dib7000p_state *state) dib7000p_set_bandwidth(state, 8000); if (state->version == SOC7090) { - dib7000p_write_word(state, 36, 0x5755);/* P_iqc_impnc_on =1 & P_iqc_corr_inh = 1 for impulsive noise */ + dib7000p_write_word(state, 36, 0x0755);/* P_iqc_impnc_on =1 & P_iqc_corr_inh = 1 for impulsive noise */ } else { if (state->cfg.tuner_is_baseband) dib7000p_write_word(state, 36, 0x0755); @@ -664,6 +680,11 @@ static int dib7000p_demod_reset(struct dib7000p_state *state) } dib7000p_write_tab(state, dib7000p_defaults); + if (state->version != SOC7090) { + dib7000p_write_word(state, 901, 0x0006); + dib7000p_write_word(state, 902, (3 << 10) | (1 << 6)); + dib7000p_write_word(state, 905, 0x2c8e); + } dib7000p_set_power_mode(state, DIB7000P_POWER_INTERFACE_ONLY); @@ -1080,9 +1101,12 @@ static int dib7000p_autosearch_start(struct dvb_frontend *demod, struct dvb_fron dib7000p_set_channel(state, &schan, 7); factor = BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth); - if (factor >= 5000) - factor = 1; - else + if (factor >= 5000) { + if (state->version == SOC7090) + factor = 2; + else + factor = 1; + } else factor = 6; value = 30 * internal * factor; @@ -1323,7 +1347,7 @@ static int dib7000p_sleep(struct dvb_frontend *demod) { struct dib7000p_state *state = demod->demodulator_priv; if (state->version == SOC7090) - return dib7090_set_output_mode(demod, OUTMODE_HIGH_Z) | dib7000p_set_power_mode(state, DIB7000P_POWER_INTERFACE_ONLY); + return dib7000p_set_power_mode(state, DIB7000P_POWER_INTERFACE_ONLY); return dib7000p_set_output_mode(state, OUTMODE_HIGH_Z) | dib7000p_set_power_mode(state, DIB7000P_POWER_INTERFACE_ONLY); } @@ -1445,10 +1469,9 @@ static int dib7000p_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_pa struct dib7000p_state *state = fe->demodulator_priv; int time, ret; - if (state->version == SOC7090) { + if (state->version == SOC7090) dib7090_set_diversity_in(fe, 0); - dib7090_set_output_mode(fe, OUTMODE_HIGH_Z); - } else + else dib7000p_set_output_mode(state, OUTMODE_HIGH_Z); /* maybe the parameter has been changed */ @@ -1485,9 +1508,13 @@ static int dib7000p_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_pa ret = dib7000p_tune(fe, fep); /* make this a config parameter */ - if (state->version == SOC7090) + if (state->version == SOC7090) { dib7090_set_output_mode(fe, state->cfg.output_mode); - else + if (state->cfg.enMpegOutput == 0) { + dib7090_setDibTxMux(state, MPEG_ON_DIBTX); + dib7090_setHostBusMux(state, DIBTX_ON_HOSTBUS); + } + } else dib7000p_set_output_mode(state, state->cfg.output_mode); return ret; @@ -1933,10 +1960,10 @@ static int dib7090_tuner_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msg[] apb_address = 915; break; case 0x27: - apb_address = 916; + apb_address = 917; break; case 0x28: - apb_address = 917; + apb_address = 916; break; case 0x1d: i = ((dib7000p_read_word(state, 72) >> 12) & 0x3); @@ -2031,12 +2058,7 @@ static u32 dib7090_calcSyncFreq(u32 P_Kin, u32 P_Kout, u32 insertExtSynchro, u32 static int dib7090_cfg_DibTx(struct dib7000p_state *state, u32 P_Kin, u32 P_Kout, u32 insertExtSynchro, u32 synchroMode, u32 syncWord, u32 syncSize) { - u8 index_buf; - u16 rx_copy_buf[22]; - dprintk("Configure DibStream Tx"); - for (index_buf = 0; index_buf < 22; index_buf++) - rx_copy_buf[index_buf] = dib7000p_read_word(state, 1536+index_buf); dib7000p_write_word(state, 1615, 1); dib7000p_write_word(state, 1603, P_Kin); @@ -2048,9 +2070,6 @@ static int dib7090_cfg_DibTx(struct dib7000p_state *state, u32 P_Kin, u32 P_Kout dib7000p_write_word(state, 1612, syncSize); dib7000p_write_word(state, 1615, 0); - for (index_buf = 0; index_buf < 22; index_buf++) - dib7000p_write_word(state, 1536+index_buf, rx_copy_buf[index_buf]); - return 0; } @@ -2077,109 +2096,121 @@ static int dib7090_cfg_DibRx(struct dib7000p_state *state, u32 P_Kin, u32 P_Kout return 0; } -static int dib7090_enDivOnHostBus(struct dib7000p_state *state) -{ - u16 reg; - - dprintk("Enable Diversity on host bus"); - reg = (1 << 8) | (1 << 5); - dib7000p_write_word(state, 1288, reg); - - return dib7090_cfg_DibTx(state, 5, 5, 0, 0, 0, 0); -} - -static int dib7090_enAdcOnHostBus(struct dib7000p_state *state) -{ - u16 reg; - - dprintk("Enable ADC on host bus"); - reg = (1 << 7) | (1 << 5); - dib7000p_write_word(state, 1288, reg); - - return dib7090_cfg_DibTx(state, 20, 5, 10, 0, 0, 0); -} - -static int dib7090_enMpegOnHostBus(struct dib7000p_state *state) +static void dib7090_enMpegMux(struct dib7000p_state *state, int onoff) { - u16 reg; - - dprintk("Enable Mpeg on host bus"); - reg = (1 << 9) | (1 << 5); - dib7000p_write_word(state, 1288, reg); + u16 reg_1287 = dib7000p_read_word(state, 1287); - return dib7090_cfg_DibTx(state, 8, 5, 0, 0, 0, 0); -} + switch (onoff) { + case 1: + reg_1287 &= ~(1<<7); + break; + case 0: + reg_1287 |= (1<<7); + break; + } -static int dib7090_enMpegInput(struct dib7000p_state *state) -{ - dprintk("Enable Mpeg input"); - return dib7090_cfg_DibRx(state, 8, 5, 0, 0, 0, 8, 0); /*outputRate = 8 */ + dib7000p_write_word(state, 1287, reg_1287); } -static int dib7090_enMpegMux(struct dib7000p_state *state, u16 pulseWidth, u16 enSerialMode, u16 enSerialClkDiv2) +static void dib7090_configMpegMux(struct dib7000p_state *state, + u16 pulseWidth, u16 enSerialMode, u16 enSerialClkDiv2) { - u16 reg = (1 << 7) | ((pulseWidth & 0x1f) << 2) | ((enSerialMode & 0x1) << 1) | (enSerialClkDiv2 & 0x1); - dprintk("Enable Mpeg mux"); - dib7000p_write_word(state, 1287, reg); - reg &= ~(1 << 7); - dib7000p_write_word(state, 1287, reg); + dib7090_enMpegMux(state, 0); - reg = (1 << 4); - dib7000p_write_word(state, 1288, reg); + /* If the input mode is MPEG do not divide the serial clock */ + if ((enSerialMode == 1) && (state->input_mode_mpeg == 1)) + enSerialClkDiv2 = 0; - return 0; + dib7000p_write_word(state, 1287, ((pulseWidth & 0x1f) << 2) + | ((enSerialMode & 0x1) << 1) + | (enSerialClkDiv2 & 0x1)); + + dib7090_enMpegMux(state, 1); } -static int dib7090_disableMpegMux(struct dib7000p_state *state) +static void dib7090_setDibTxMux(struct dib7000p_state *state, int mode) { - u16 reg; - - dprintk("Disable Mpeg mux"); - dib7000p_write_word(state, 1288, 0); + u16 reg_1288 = dib7000p_read_word(state, 1288) & ~(0x7 << 7); - reg = dib7000p_read_word(state, 1287); - reg &= ~(1 << 7); - dib7000p_write_word(state, 1287, reg); - - return 0; + switch (mode) { + case MPEG_ON_DIBTX: + dprintk("SET MPEG ON DIBSTREAM TX"); + dib7090_cfg_DibTx(state, 8, 5, 0, 0, 0, 0); + reg_1288 |= (1<<9); + break; + case DIV_ON_DIBTX: + dprintk("SET DIV_OUT ON DIBSTREAM TX"); + dib7090_cfg_DibTx(state, 5, 5, 0, 0, 0, 0); + reg_1288 |= (1<<8); + break; + case ADC_ON_DIBTX: + dprintk("SET ADC_OUT ON DIBSTREAM TX"); + dib7090_cfg_DibTx(state, 20, 5, 10, 0, 0, 0); + reg_1288 |= (1<<7); + break; + default: + break; + } + dib7000p_write_word(state, 1288, reg_1288); } -static int dib7090_set_input_mode(struct dvb_frontend *fe, int mode) +static void dib7090_setHostBusMux(struct dib7000p_state *state, int mode) { - struct dib7000p_state *state = fe->demodulator_priv; + u16 reg_1288 = dib7000p_read_word(state, 1288) & ~(0x7 << 4); switch (mode) { - case INPUT_MODE_DIVERSITY: - dprintk("Enable diversity INPUT"); - dib7090_cfg_DibRx(state, 5, 5, 0, 0, 0, 0, 0); + case DEMOUT_ON_HOSTBUS: + dprintk("SET DEM OUT OLD INTERF ON HOST BUS"); + dib7090_enMpegMux(state, 0); + reg_1288 |= (1<<6); + break; + case DIBTX_ON_HOSTBUS: + dprintk("SET DIBSTREAM TX ON HOST BUS"); + dib7090_enMpegMux(state, 0); + reg_1288 |= (1<<5); break; - case INPUT_MODE_MPEG: - dprintk("Enable Mpeg INPUT"); - dib7090_cfg_DibRx(state, 8, 5, 0, 0, 0, 8, 0); /*outputRate = 8 */ + case MPEG_ON_HOSTBUS: + dprintk("SET MPEG MUX ON HOST BUS"); + reg_1288 |= (1<<4); break; - case INPUT_MODE_OFF: default: - dprintk("Disable INPUT"); - dib7090_cfg_DibRx(state, 0, 0, 0, 0, 0, 0, 0); break; } - return 0; + dib7000p_write_word(state, 1288, reg_1288); } -static int dib7090_set_diversity_in(struct dvb_frontend *fe, int onoff) +int dib7090_set_diversity_in(struct dvb_frontend *fe, int onoff) { + struct dib7000p_state *state = fe->demodulator_priv; + u16 reg_1287; + switch (onoff) { - case 0: /* only use the internal way - not the diversity input */ - dib7090_set_input_mode(fe, INPUT_MODE_MPEG); - break; - case 1: /* both ways */ - case 2: /* only the diversity input */ - dib7090_set_input_mode(fe, INPUT_MODE_DIVERSITY); - break; + case 0: /* only use the internal way - not the diversity input */ + dprintk("%s mode OFF : by default Enable Mpeg INPUT", __func__); + dib7090_cfg_DibRx(state, 8, 5, 0, 0, 0, 8, 0); + + /* Do not divide the serial clock of MPEG MUX */ + /* in SERIAL MODE in case input mode MPEG is used */ + reg_1287 = dib7000p_read_word(state, 1287); + /* enSerialClkDiv2 == 1 ? */ + if ((reg_1287 & 0x1) == 1) { + /* force enSerialClkDiv2 = 0 */ + reg_1287 &= ~0x1; + dib7000p_write_word(state, 1287, reg_1287); + } + state->input_mode_mpeg = 1; + break; + case 1: /* both ways */ + case 2: /* only the diversity input */ + dprintk("%s ON : Enable diversity INPUT", __func__); + dib7090_cfg_DibRx(state, 5, 5, 0, 0, 0, 0, 0); + state->input_mode_mpeg = 0; + break; } + dib7000p_set_diversity_in(&state->demod, onoff); return 0; } @@ -2204,69 +2235,63 @@ static int dib7090_set_output_mode(struct dvb_frontend *fe, int mode) case OUTMODE_MPEG2_SERIAL: if (prefer_mpeg_mux_use) { - dprintk("Sip 7090P setting output mode TS_SERIAL using Mpeg Mux"); - dib7090_enMpegOnHostBus(state); - dib7090_enMpegInput(state); - if (state->cfg.enMpegOutput == 1) - dib7090_enMpegMux(state, 3, 1, 1); - - } else { /* Use Smooth block */ - dprintk("Sip 7090P setting output mode TS_SERIAL using Smooth bloc"); - dib7090_disableMpegMux(state); - dib7000p_write_word(state, 1288, (1 << 6)); - outreg |= (2 << 6) | (0 << 1); + dprintk("setting output mode TS_SERIAL using Mpeg Mux"); + dib7090_configMpegMux(state, 3, 1, 1); + dib7090_setHostBusMux(state, MPEG_ON_HOSTBUS); + } else {/* Use Smooth block */ + dprintk("setting output mode TS_SERIAL using Smooth bloc"); + dib7090_setHostBusMux(state, DEMOUT_ON_HOSTBUS); + outreg |= (2<<6) | (0 << 1); } break; case OUTMODE_MPEG2_PAR_GATED_CLK: if (prefer_mpeg_mux_use) { - dprintk("Sip 7090P setting output mode TS_PARALLEL_GATED using Mpeg Mux"); - dib7090_enMpegOnHostBus(state); - dib7090_enMpegInput(state); - if (state->cfg.enMpegOutput == 1) - dib7090_enMpegMux(state, 2, 0, 0); - } else { /* Use Smooth block */ - dprintk("Sip 7090P setting output mode TS_PARALLEL_GATED using Smooth block"); - dib7090_disableMpegMux(state); - dib7000p_write_word(state, 1288, (1 << 6)); - outreg |= (0 << 6); + dprintk("setting output mode TS_PARALLEL_GATED using Mpeg Mux"); + dib7090_configMpegMux(state, 2, 0, 0); + dib7090_setHostBusMux(state, MPEG_ON_HOSTBUS); + } else { /* Use Smooth block */ + dprintk("setting output mode TS_PARALLEL_GATED using Smooth block"); + dib7090_setHostBusMux(state, DEMOUT_ON_HOSTBUS); + outreg |= (0<<6); } break; case OUTMODE_MPEG2_PAR_CONT_CLK: /* Using Smooth block only */ - dprintk("Sip 7090P setting output mode TS_PARALLEL_CONT using Smooth block"); - dib7090_disableMpegMux(state); - dib7000p_write_word(state, 1288, (1 << 6)); - outreg |= (1 << 6); + dprintk("setting output mode TS_PARALLEL_CONT using Smooth block"); + dib7090_setHostBusMux(state, DEMOUT_ON_HOSTBUS); + outreg |= (1<<6); break; case OUTMODE_MPEG2_FIFO: /* Using Smooth block because not supported by new Mpeg Mux bloc */ - dprintk("Sip 7090P setting output mode TS_FIFO using Smooth block"); - dib7090_disableMpegMux(state); - dib7000p_write_word(state, 1288, (1 << 6)); - outreg |= (5 << 6); + dprintk("setting output mode TS_FIFO using Smooth block"); + dib7090_setHostBusMux(state, DEMOUT_ON_HOSTBUS); + outreg |= (5<<6); smo_mode |= (3 << 1); fifo_threshold = 512; break; case OUTMODE_DIVERSITY: - dprintk("Sip 7090P setting output mode MODE_DIVERSITY"); - dib7090_disableMpegMux(state); - dib7090_enDivOnHostBus(state); + dprintk("setting output mode MODE_DIVERSITY"); + dib7090_setDibTxMux(state, DIV_ON_DIBTX); + dib7090_setHostBusMux(state, DIBTX_ON_HOSTBUS); break; case OUTMODE_ANALOG_ADC: - dprintk("Sip 7090P setting output mode MODE_ANALOG_ADC"); - dib7090_enAdcOnHostBus(state); + dprintk("setting output mode MODE_ANALOG_ADC"); + dib7090_setDibTxMux(state, ADC_ON_DIBTX); + dib7090_setHostBusMux(state, DIBTX_ON_HOSTBUS); break; } + if (mode != OUTMODE_HIGH_Z) + outreg |= (1 << 10); if (state->cfg.output_mpeg2_in_188_bytes) smo_mode |= (1 << 5); ret |= dib7000p_write_word(state, 235, smo_mode); ret |= dib7000p_write_word(state, 236, fifo_threshold); /* synchronous fread */ - ret |= dib7000p_write_word(state, 1286, outreg | (1 << 10)); /* allways set Dout active = 1 !!! */ + ret |= dib7000p_write_word(state, 1286, outreg); return ret; } @@ -2296,13 +2321,6 @@ int dib7090_tuner_sleep(struct dvb_frontend *fe, int onoff) } EXPORT_SYMBOL(dib7090_tuner_sleep); -int dib7090_agc_restart(struct dvb_frontend *fe, u8 restart) -{ - dprintk("AGC restart callback: %d", restart); - return 0; -} -EXPORT_SYMBOL(dib7090_agc_restart); - int dib7090_get_adc_power(struct dvb_frontend *fe) { return dib7000p_get_adc_power(fe); diff --git a/drivers/media/dvb/frontends/dib7000p.h b/drivers/media/dvb/frontends/dib7000p.h index 0179f94..58f907c 100644 --- a/drivers/media/dvb/frontends/dib7000p.h +++ b/drivers/media/dvb/frontends/dib7000p.h @@ -56,7 +56,6 @@ extern int dib7000p_pid_filter(struct dvb_frontend *, u8 id, u16 pid, u8 onoff); extern int dib7000p_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff); extern int dib7000p_update_pll(struct dvb_frontend *fe, struct dibx000_bandwidth_config *bw); extern u32 dib7000p_ctrl_timf(struct dvb_frontend *fe, u8 op, u32 timf); -extern int dib7090_agc_restart(struct dvb_frontend *fe, u8 restart); extern int dib7090_tuner_sleep(struct dvb_frontend *fe, int onoff); extern int dib7090_get_adc_power(struct dvb_frontend *fe); extern struct i2c_adapter *dib7090_get_i2c_tuner(struct dvb_frontend *fe); @@ -122,12 +121,6 @@ static inline u32 dib7000p_ctrl_timf(struct dvb_frontend *fe, u8 op, u32 timf) return 0; } -static inline int dib7090_agc_restart(struct dvb_frontend *fe, u8 restart) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return -ENODEV; -} - static inline int dib7090_tuner_sleep(struct dvb_frontend *fe, int onoff) { printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); -- cgit v0.10.2 From 6724a2f4f7a6cb9251641a46e1ab06bb85adf1b5 Mon Sep 17 00:00:00 2001 From: Olivier Grenie Date: Fri, 5 Aug 2011 13:49:33 -0300 Subject: [media] dib7090: add the reference board TFE7090E The intend of this patch is to add the support for the DiBcom reference board TFE7090E. Signed-off-by: Olivier Grenie Signed-off-by: Patrick Boettcher Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/dvb/dvb-usb/dib0700_devices.c b/drivers/media/dvb/dvb-usb/dib0700_devices.c index 771dfda..aeab321 100644 --- a/drivers/media/dvb/dvb-usb/dib0700_devices.c +++ b/drivers/media/dvb/dvb-usb/dib0700_devices.c @@ -1518,7 +1518,7 @@ static int dib8096_set_param_override(struct dvb_frontend *fe, if (ret < 0) return ret; - target = (dib0090_get_wbd_offset(fe) * 8 * 18 / 33 + 1) / 2; + target = (dib0090_get_wbd_target(fe) * 8 * 18 / 33 + 1) / 2; dib8000_set_wbd_ref(fe, target); @@ -2079,7 +2079,7 @@ static int dib7090_agc_startup(struct dvb_frontend *fe, struct dvb_frontend_para memset(&pll, 0, sizeof(struct dibx000_bandwidth_config)); dib0090_pwm_gain_reset(fe); - target = (dib0090_get_wbd_offset(fe) * 8 + 1) / 2; + target = (dib0090_get_wbd_target(fe) * 8 + 1) / 2; dib7000p_set_wbd_ref(fe, target); if (dib7090p_get_best_sampling(fe, &adc) == 0) { @@ -2100,6 +2100,41 @@ static int dib7090_agc_restart(struct dvb_frontend *fe, u8 restart) return 0; } +static int dib7090e_update_lna(struct dvb_frontend *fe, u16 agc_global) +{ + u16 agc1 = 0, agc2, wbd = 0, wbd_target, wbd_offset, threshold_agc1; + s16 wbd_delta; + + if ((fe->dtv_property_cache.frequency) < 400000000) + threshold_agc1 = 25000; + else + threshold_agc1 = 30000; + + wbd_target = (dib0090_get_wbd_target(fe)*8+1)/2; + wbd_offset = dib0090_get_wbd_offset(fe); + dib7000p_get_agc_values(fe, NULL, &agc1, &agc2, &wbd); + wbd_delta = (s16)wbd - (((s16)wbd_offset+10)*4) ; + + deb_info("update lna, agc_global=%d agc1=%d agc2=%d", + agc_global, agc1, agc2); + deb_info("update lna, wbd=%d wbd target=%d wbd offset=%d wbd delta=%d", + wbd, wbd_target, wbd_offset, wbd_delta); + + if ((agc1 < threshold_agc1) && (wbd_delta > 0)) { + dib0090_set_switch(fe, 1, 1, 1); + dib0090_set_vga(fe, 0); + dib0090_update_rframp_7090(fe, 0); + dib0090_update_tuning_table_7090(fe, 0); + } else { + dib0090_set_vga(fe, 1); + dib0090_update_rframp_7090(fe, 1); + dib0090_update_tuning_table_7090(fe, 1); + dib0090_set_switch(fe, 0, 0, 0); + } + + return 0; +} + static struct dib0090_wbd_slope dib7090_wbd_table[] = { { 380, 81, 850, 64, 540, 4}, { 860, 51, 866, 21, 375, 4}, @@ -2108,6 +2143,15 @@ static struct dib0090_wbd_slope dib7090_wbd_table[] = { { 0xFFFF, 0, 0, 0, 0, 0}, }; +static struct dib0090_wbd_slope dib7090e_wbd_table[] = { + { 380, 81, 850, 64, 540, 4}, + { 700, 51, 866, 21, 320, 4}, + { 860, 48, 666, 18, 330, 6}, + {1700, 0, 250, 0, 100, 6}, + {2600, 0, 250, 0, 100, 6}, + { 0xFFFF, 0, 0, 0, 0, 0}, +}; + struct dibx000_agc_config dib7090_agc_config[2] = { { .band_caps = BAND_UHF, @@ -2286,6 +2330,34 @@ static struct dib7000p_config tfe7090pvr_dib7000p_config[2] = { } }; +static struct dib7000p_config tfe7090e_dib7000p_config = { + .output_mpeg2_in_188_bytes = 1, + .hostbus_diversity = 1, + .tuner_is_baseband = 1, + .update_lna = dib7090e_update_lna, + + .agc_config_count = 2, + .agc = dib7090_agc_config, + + .bw = &dib7090_clock_config_12_mhz, + + .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS, + .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES, + .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS, + + .pwm_freq_div = 0, + + .agc_control = dib7090_agc_restart, + + .spur_protect = 0, + .disable_sample_and_hold = 0, + .enable_current_mirror = 0, + .diversity_delay = 0, + + .output_mode = OUTMODE_MPEG2_FIFO, + .enMpegOutput = 1, +}; + static const struct dib0090_config nim7090_dib0090_config = { .io.clock_khz = 12000, .io.pll_bypass = 0, @@ -2320,6 +2392,42 @@ static const struct dib0090_config nim7090_dib0090_config = { .in_soc = 1, }; +static const struct dib0090_config tfe7090e_dib0090_config = { + .io.clock_khz = 12000, + .io.pll_bypass = 0, + .io.pll_range = 0, + .io.pll_prediv = 3, + .io.pll_loopdiv = 6, + .io.adc_clock_ratio = 0, + .io.pll_int_loop_filt = 0, + .reset = dib7090_tuner_sleep, + .sleep = dib7090_tuner_sleep, + + .freq_offset_khz_uhf = 0, + .freq_offset_khz_vhf = 0, + + .get_adc_power = dib7090_get_adc_power, + + .clkouttobamse = 1, + .analog_output = 0, + + .wbd_vhf_offset = 0, + .wbd_cband_offset = 0, + .use_pwm_agc = 1, + .clkoutdrive = 0, + + .fref_clock_ratio = 0, + + .wbd = dib7090e_wbd_table, + + .ls_cfg_pad_drv = 0, + .data_tx_drv = 0, + .low_if = NULL, + .in_soc = 1, + .force_cband_input = 1, + .is_dib7090e = 1, +}; + static const struct dib0090_config tfe7090pvr_dib0090_config[2] = { { .io.clock_khz = 12000, @@ -2512,6 +2620,49 @@ static int tfe7090pvr_tuner1_attach(struct dvb_usb_adapter *adap) return 0; } +static int tfe7090e_frontend_attach(struct dvb_usb_adapter *adap) +{ + dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1); + msleep(20); + dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1); + dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1); + dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1); + dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0); + + msleep(20); + dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1); + msleep(20); + dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1); + + if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, + 1, 0x10, &tfe7090e_dib7000p_config) != 0) { + err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n", + __func__); + return -ENODEV; + } + adap->fe_adap[0].fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, + 0x80, &tfe7090e_dib7000p_config); + + return adap->fe_adap[0].fe == NULL ? -ENODEV : 0; +} + +static int tfe7090e_tuner_attach(struct dvb_usb_adapter *adap) +{ + struct dib0700_adapter_state *st = adap->priv; + struct i2c_adapter *tun_i2c = + dib7090_get_i2c_tuner(adap->fe_adap[0].fe); + + if (dvb_attach(dib0090_register, adap->fe_adap[0].fe, tun_i2c, + &tfe7090e_dib0090_config) == NULL) + return -ENODEV; + + dib7000p_set_gpio(adap->fe_adap[0].fe, 8, 0, 1); + + st->set_param_save = adap->fe_adap[0].fe->ops.tuner_ops.set_params; + adap->fe_adap[0].fe->ops.tuner_ops.set_params = dib7090_agc_startup; + return 0; +} + /* STK7070PD */ static struct dib7000p_config stk7070pd_dib7000p_config[2] = { { @@ -2968,6 +3119,7 @@ struct usb_device_id dib0700_usb_id_table[] = { /* 75 */{ USB_DEVICE(USB_VID_MEDION, USB_PID_CREATIX_CTX1921) }, { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV340E) }, { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV340E_SE) }, + { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_TFE7090E) }, { 0 } /* Terminating entry */ }; MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table); @@ -4033,6 +4185,46 @@ struct dvb_usb_device_properties dib0700_devices[] = { RC_TYPE_NEC, .change_protocol = dib0700_change_protocol, }, + }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, + .num_adapters = 1, + .adapter = { + { + .num_frontends = 1, + .fe = {{ + .caps = DVB_USB_ADAP_HAS_PID_FILTER | + DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, + .pid_filter_count = 32, + .pid_filter = stk70x0p_pid_filter, + .pid_filter_ctrl = stk70x0p_pid_filter_ctrl, + .frontend_attach = tfe7090e_frontend_attach, + .tuner_attach = tfe7090e_tuner_attach, + + DIB0700_DEFAULT_STREAMING_CONFIG(0x02), + } }, + + .size_of_priv = + sizeof(struct dib0700_adapter_state), + }, + }, + + .num_device_descs = 1, + .devices = { + { "DiBcom TFE7090E reference design", + { &dib0700_usb_id_table[78], NULL }, + { NULL }, + }, + }, + + .rc.core = { + .rc_interval = DEFAULT_RC_INTERVAL, + .rc_codes = RC_MAP_DIB0700_RC5_TABLE, + .module_name = "dib0700", + .rc_query = dib0700_rc_query_old_firmware, + .allowed_protos = RC_TYPE_RC5 | + RC_TYPE_RC6 | + RC_TYPE_NEC, + .change_protocol = dib0700_change_protocol, + }, }, }; diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h index 0040aa2..908a616 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h +++ b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h @@ -113,6 +113,7 @@ #define USB_PID_DIBCOM_STK7770P 0x1e80 #define USB_PID_DIBCOM_NIM7090 0x1bb2 #define USB_PID_DIBCOM_TFE7090PVR 0x1bb4 +#define USB_PID_DIBCOM_TFE7090E 0x1bb7 #define USB_PID_DIBCOM_NIM9090M 0x2383 #define USB_PID_DIBCOM_NIM9090MD 0x2384 #define USB_PID_DPOSH_M9206_COLD 0x9206 diff --git a/drivers/media/dvb/frontends/dib0090.c b/drivers/media/dvb/frontends/dib0090.c index 9030f3d..26c6c61 100644 --- a/drivers/media/dvb/frontends/dib0090.c +++ b/drivers/media/dvb/frontends/dib0090.c @@ -717,6 +717,34 @@ static const u16 rf_ramp_pwm_cband_7090[] = { (0 << 10) | 109, /* RF_RAMP4, LNA 4 */ }; +static const uint16_t rf_ramp_pwm_cband_7090e_sensitivity[] = { + 186, + 40, + 746, + (10 << 10) | 345, + (0 << 10) | 746, + (0 << 10) | 0, + (0 << 10) | 0, + (28 << 10) | 200, + (0 << 10) | 345, + (20 << 10) | 0, + (0 << 10) | 200, +}; + +static const uint16_t rf_ramp_pwm_cband_7090e_aci[] = { + 86, + 40, + 345, + (0 << 10) | 0, + (0 << 10) | 0, + (0 << 10) | 0, + (0 << 10) | 0, + (28 << 10) | 200, + (0 << 10) | 345, + (20 << 10) | 0, + (0 << 10) | 200, +}; + static const u16 rf_ramp_pwm_cband_8090[] = { 345, /* max RF gain in 10th of dB */ 29, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> RF_RAMP2 */ @@ -1076,8 +1104,16 @@ void dib0090_pwm_gain_reset(struct dvb_frontend *fe) dib0090_set_bbramp_pwm(state, bb_ramp_pwm_normal_socs); if (state->identity.version == SOC_8090_P1G_11R1 || state->identity.version == SOC_8090_P1G_21R1) dib0090_set_rframp_pwm(state, rf_ramp_pwm_cband_8090); - else if (state->identity.version == SOC_7090_P1G_11R1 || state->identity.version == SOC_7090_P1G_21R1) - dib0090_set_rframp_pwm(state, rf_ramp_pwm_cband_7090); + else if (state->identity.version == SOC_7090_P1G_11R1 + || state->identity.version == SOC_7090_P1G_21R1) { + if (state->config->is_dib7090e) { + if (state->rf_ramp == NULL) + dib0090_set_rframp_pwm(state, rf_ramp_pwm_cband_7090e_sensitivity); + else + dib0090_set_rframp_pwm(state, state->rf_ramp); + } else + dib0090_set_rframp_pwm(state, rf_ramp_pwm_cband_7090); + } } else { dib0090_set_rframp_pwm(state, rf_ramp_pwm_cband); dib0090_set_bbramp_pwm(state, bb_ramp_pwm_normal); @@ -1313,7 +1349,7 @@ void dib0090_get_current_gain(struct dvb_frontend *fe, u16 * rf, u16 * bb, u16 * EXPORT_SYMBOL(dib0090_get_current_gain); -u16 dib0090_get_wbd_offset(struct dvb_frontend *fe) +u16 dib0090_get_wbd_target(struct dvb_frontend *fe) { struct dib0090_state *state = fe->tuner_priv; u32 f_MHz = state->fe->dtv_property_cache.frequency / 1000000; @@ -1350,9 +1386,57 @@ u16 dib0090_get_wbd_offset(struct dvb_frontend *fe) return state->wbd_offset + wbd_tcold; } +EXPORT_SYMBOL(dib0090_get_wbd_target); +u16 dib0090_get_wbd_offset(struct dvb_frontend *fe) +{ + struct dib0090_state *state = fe->tuner_priv; + return state->wbd_offset; +} EXPORT_SYMBOL(dib0090_get_wbd_offset); +int dib0090_set_switch(struct dvb_frontend *fe, u8 sw1, u8 sw2, u8 sw3) +{ + struct dib0090_state *state = fe->tuner_priv; + + dib0090_write_reg(state, 0x0b, (dib0090_read_reg(state, 0x0b) & 0xfff8) + | ((sw3 & 1) << 2) | ((sw2 & 1) << 1) | (sw1 & 1)); + + return 0; +} +EXPORT_SYMBOL(dib0090_set_switch); + +int dib0090_set_vga(struct dvb_frontend *fe, u8 onoff) +{ + struct dib0090_state *state = fe->tuner_priv; + + dib0090_write_reg(state, 0x09, (dib0090_read_reg(state, 0x09) & 0x7fff) + | ((onoff & 1) << 15)); + return 0; +} +EXPORT_SYMBOL(dib0090_set_vga); + +int dib0090_update_rframp_7090(struct dvb_frontend *fe, u8 cfg_sensitivity) +{ + struct dib0090_state *state = fe->tuner_priv; + + if ((!state->identity.p1g) || (!state->identity.in_soc) + || ((state->identity.version != SOC_7090_P1G_21R1) + && (state->identity.version != SOC_7090_P1G_11R1))) { + dprintk("%s() function can only be used for dib7090P", __func__); + return -ENODEV; + } + + if (cfg_sensitivity) + state->rf_ramp = (const u16 *)&rf_ramp_pwm_cband_7090e_sensitivity; + else + state->rf_ramp = (const u16 *)&rf_ramp_pwm_cband_7090e_aci; + dib0090_pwm_gain_reset(fe); + + return 0; +} +EXPORT_SYMBOL(dib0090_update_rframp_7090); + static const u16 dib0090_defaults[] = { 25, 0x01, @@ -1962,6 +2046,52 @@ static const struct dib0090_tuning dib0090_tuning_table_cband_7090[] = { #endif }; +static const struct dib0090_tuning dib0090_tuning_table_cband_7090e_sensitivity[] = { +#ifdef CONFIG_BAND_CBAND + { 300000, 0 , 3, 0x8105, 0x2c0, 0x2d12, 0xb84e, EN_CAB }, + { 380000, 0 , 10, 0x810F, 0x2c0, 0x2d12, 0xb84e, EN_CAB }, + { 600000, 0 , 10, 0x815E, 0x280, 0x2d12, 0xb84e, EN_CAB }, + { 660000, 0 , 5, 0x85E3, 0x280, 0x2d12, 0xb84e, EN_CAB }, + { 720000, 0 , 5, 0x852E, 0x280, 0x2d12, 0xb84e, EN_CAB }, + { 860000, 0 , 4, 0x85E5, 0x280, 0x2d12, 0xb84e, EN_CAB }, +#endif +}; + +int dib0090_update_tuning_table_7090(struct dvb_frontend *fe, + u8 cfg_sensitivity) +{ + struct dib0090_state *state = fe->tuner_priv; + const struct dib0090_tuning *tune = + dib0090_tuning_table_cband_7090e_sensitivity; + const struct dib0090_tuning dib0090_tuning_table_cband_7090e_aci[] = { + { 300000, 0 , 3, 0x8165, 0x2c0, 0x2d12, 0xb84e, EN_CAB }, + { 650000, 0 , 4, 0x815B, 0x280, 0x2d12, 0xb84e, EN_CAB }, + { 860000, 0 , 5, 0x84EF, 0x280, 0x2d12, 0xb84e, EN_CAB }, + }; + + if ((!state->identity.p1g) || (!state->identity.in_soc) + || ((state->identity.version != SOC_7090_P1G_21R1) + && (state->identity.version != SOC_7090_P1G_11R1))) { + dprintk("%s() function can only be used for dib7090", __func__); + return -ENODEV; + } + + if (cfg_sensitivity) + tune = dib0090_tuning_table_cband_7090e_sensitivity; + else + tune = dib0090_tuning_table_cband_7090e_aci; + + while (state->rf_request > tune->max_freq) + tune++; + + dib0090_write_reg(state, 0x09, (dib0090_read_reg(state, 0x09) & 0x8000) + | (tune->lna_bias & 0x7fff)); + dib0090_write_reg(state, 0x0b, (dib0090_read_reg(state, 0x0b) & 0xf83f) + | ((tune->lna_tune << 6) & 0x07c0)); + return 0; +} +EXPORT_SYMBOL(dib0090_update_tuning_table_7090); + static int dib0090_captrim_search(struct dib0090_state *state, enum frontend_tune_state *tune_state) { int ret = 0; @@ -2210,12 +2340,18 @@ static int dib0090_tune(struct dvb_frontend *fe) if (state->current_band & BAND_CBAND || state->current_band & BAND_FM || state->current_band & BAND_VHF || state->current_band & BAND_UHF) { state->current_band = BAND_CBAND; - tune = dib0090_tuning_table_cband_7090; + if (state->config->is_dib7090e) + tune = dib0090_tuning_table_cband_7090e_sensitivity; + else + tune = dib0090_tuning_table_cband_7090; } } else { /* Use the CBAND input for all band under UHF */ if (state->current_band & BAND_CBAND || state->current_band & BAND_FM || state->current_band & BAND_VHF) { state->current_band = BAND_CBAND; - tune = dib0090_tuning_table_cband_7090; + if (state->config->is_dib7090e) + tune = dib0090_tuning_table_cband_7090e_sensitivity; + else + tune = dib0090_tuning_table_cband_7090; } } } else diff --git a/drivers/media/dvb/frontends/dib0090.h b/drivers/media/dvb/frontends/dib0090.h index 648318a..781dc49 100644 --- a/drivers/media/dvb/frontends/dib0090.h +++ b/drivers/media/dvb/frontends/dib0090.h @@ -80,14 +80,21 @@ extern struct dvb_frontend *dib0090_register(struct dvb_frontend *fe, struct i2c extern struct dvb_frontend *dib0090_fw_register(struct dvb_frontend *fe, struct i2c_adapter *i2c, const struct dib0090_config *config); extern void dib0090_dcc_freq(struct dvb_frontend *fe, u8 fast); extern void dib0090_pwm_gain_reset(struct dvb_frontend *fe); -extern u16 dib0090_get_wbd_offset(struct dvb_frontend *tuner); +extern u16 dib0090_get_wbd_target(struct dvb_frontend *tuner); +extern u16 dib0090_get_wbd_offset(struct dvb_frontend *fe); extern int dib0090_gain_control(struct dvb_frontend *fe); extern enum frontend_tune_state dib0090_get_tune_state(struct dvb_frontend *fe); extern int dib0090_set_tune_state(struct dvb_frontend *fe, enum frontend_tune_state tune_state); extern void dib0090_get_current_gain(struct dvb_frontend *fe, u16 * rf, u16 * bb, u16 * rf_gain_limit, u16 * rflt); extern void dib0090_set_dc_servo(struct dvb_frontend *fe, u8 DC_servo_cutoff); +extern int dib0090_set_switch(struct dvb_frontend *fe, u8 sw1, u8 sw2, u8 sw3); +extern int dib0090_set_vga(struct dvb_frontend *fe, u8 onoff); +extern int dib0090_update_rframp_7090(struct dvb_frontend *fe, + u8 cfg_sensitivity); +extern int dib0090_update_tuning_table_7090(struct dvb_frontend *fe, + u8 cfg_sensitivity); #else -static inline struct dvb_frontend *dib0090_register(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct dib0090_config *config) +static inline struct dvb_frontend *dib0090_register(struct dvb_frontend *fe, struct i2c_adapter *i2c, const struct dib0090_config *config) { printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); return NULL; @@ -109,7 +116,13 @@ static inline void dib0090_pwm_gain_reset(struct dvb_frontend *fe) printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); } -static inline u16 dib0090_get_wbd_offset(struct dvb_frontend *tuner) +static inline u16 dib0090_get_wbd_target(struct dvb_frontend *tuner) +{ + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); + return 0; +} + +static inline u16 dib0090_get_wbd_offset(struct dvb_frontend *fe) { printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); return 0; @@ -142,6 +155,33 @@ static inline void dib0090_set_dc_servo(struct dvb_frontend *fe, u8 DC_servo_cut { printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); } + +static inline int dib0090_set_switch(struct dvb_frontend *fe, + u8 sw1, u8 sw2, u8 sw3) +{ + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); + return -ENODEV; +} + +static inline int dib0090_set_vga(struct dvb_frontend *fe, u8 onoff) +{ + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); + return -ENODEV; +} + +static inline int dib0090_update_rframp_7090(struct dvb_frontend *fe, + u8 cfg_sensitivity) +{ + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); + return -ENODEV; +} + +static inline int dib0090_update_tuning_table_7090(struct dvb_frontend *fe, + u8 cfg_sensitivity) +{ + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); + return -ENODEV; +} #endif #endif diff --git a/drivers/media/dvb/frontends/dib7000p.c b/drivers/media/dvb/frontends/dib7000p.c index 08e62a4..2b52542 100644 --- a/drivers/media/dvb/frontends/dib7000p.c +++ b/drivers/media/dvb/frontends/dib7000p.c @@ -418,6 +418,24 @@ int dib7000p_set_wbd_ref(struct dvb_frontend *demod, u16 value) } EXPORT_SYMBOL(dib7000p_set_wbd_ref); +int dib7000p_get_agc_values(struct dvb_frontend *fe, + u16 *agc_global, u16 *agc1, u16 *agc2, u16 *wbd) +{ + struct dib7000p_state *state = fe->demodulator_priv; + + if (agc_global != NULL) + *agc_global = dib7000p_read_word(state, 394); + if (agc1 != NULL) + *agc1 = dib7000p_read_word(state, 392); + if (agc2 != NULL) + *agc2 = dib7000p_read_word(state, 393); + if (wbd != NULL) + *wbd = dib7000p_read_word(state, 397); + + return 0; +} +EXPORT_SYMBOL(dib7000p_get_agc_values); + static void dib7000p_reset_pll(struct dib7000p_state *state) { struct dibx000_bandwidth_config *bw = &state->cfg.bw[0]; diff --git a/drivers/media/dvb/frontends/dib7000p.h b/drivers/media/dvb/frontends/dib7000p.h index 58f907c..b61b03a 100644 --- a/drivers/media/dvb/frontends/dib7000p.h +++ b/drivers/media/dvb/frontends/dib7000p.h @@ -60,6 +60,8 @@ extern int dib7090_tuner_sleep(struct dvb_frontend *fe, int onoff); extern int dib7090_get_adc_power(struct dvb_frontend *fe); extern struct i2c_adapter *dib7090_get_i2c_tuner(struct dvb_frontend *fe); extern int dib7090_slave_reset(struct dvb_frontend *fe); +extern int dib7000p_get_agc_values(struct dvb_frontend *fe, + u16 *agc_global, u16 *agc1, u16 *agc2, u16 *wbd); #else static inline struct dvb_frontend *dib7000p_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib7000p_config *cfg) { @@ -144,6 +146,13 @@ static inline int dib7090_slave_reset(struct dvb_frontend *fe) printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); return -ENODEV; } + +static inline int dib7000p_get_agc_values(struct dvb_frontend *fe, + u16 *agc_global, u16 *agc1, u16 *agc2, u16 *wbd) +{ + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); + return -ENODEV; +} #endif #endif -- cgit v0.10.2 From a685dbbc65e1e0f266e69a538dfd65a2f10fcc91 Mon Sep 17 00:00:00 2001 From: Olivier Grenie Date: Fri, 5 Aug 2011 14:10:40 -0300 Subject: [media] DiBcom: correct warnings The intend of this patch is to correct some warnings given. Signed-off-by: Olivier Grenie Signed-off-by: Patrick Boettcher Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/dvb/dvb-usb/dib0700_devices.c b/drivers/media/dvb/dvb-usb/dib0700_devices.c index aeab321..d82740a 100644 --- a/drivers/media/dvb/dvb-usb/dib0700_devices.c +++ b/drivers/media/dvb/dvb-usb/dib0700_devices.c @@ -1328,7 +1328,7 @@ static int stk807xpvr_frontend_attach1(struct dvb_usb_adapter *adap) } /* STK8096GP */ -struct dibx000_agc_config dib8090_agc_config[2] = { +static struct dibx000_agc_config dib8090_agc_config[2] = { { BAND_UHF | BAND_VHF | BAND_LBAND | BAND_SBAND, /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=1, @@ -2152,7 +2152,7 @@ static struct dib0090_wbd_slope dib7090e_wbd_table[] = { { 0xFFFF, 0, 0, 0, 0, 0}, }; -struct dibx000_agc_config dib7090_agc_config[2] = { +static struct dibx000_agc_config dib7090_agc_config[2] = { { .band_caps = BAND_UHF, /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=1, P_agc_inv_pwm1=0, P_agc_inv_pwm2=0, diff --git a/drivers/media/dvb/frontends/dib0090.c b/drivers/media/dvb/frontends/dib0090.c index 26c6c61..2b30ab2 100644 --- a/drivers/media/dvb/frontends/dib0090.c +++ b/drivers/media/dvb/frontends/dib0090.c @@ -1522,7 +1522,7 @@ static void dib0090_set_default_config(struct dib0090_state *state, const u16 * #define POLY_MIN (u8) 0 #define POLY_MAX (u8) 8 -void dib0090_set_EFUSE(struct dib0090_state *state) +static void dib0090_set_EFUSE(struct dib0090_state *state) { u8 c, h, n; u16 e2, e4; diff --git a/drivers/media/dvb/frontends/dib7000p.c b/drivers/media/dvb/frontends/dib7000p.c index 2b52542..3ab695b 100644 --- a/drivers/media/dvb/frontends/dib7000p.c +++ b/drivers/media/dvb/frontends/dib7000p.c @@ -1876,7 +1876,8 @@ static int w7090p_tuner_rw_serpar(struct i2c_adapter *i2c_adap, struct i2c_msg m return num; } -int dib7090p_rw_on_apb(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num, u16 apb_address) +static int dib7090p_rw_on_apb(struct i2c_adapter *i2c_adap, + struct i2c_msg msg[], int num, u16 apb_address) { struct dib7000p_state *state = i2c_get_adapdata(i2c_adap); u16 word; -- cgit v0.10.2 From 1f6bfcc752445ea03cb63c0c6bf5ee54d0fa73d5 Mon Sep 17 00:00:00 2001 From: Olivier Grenie Date: Mon, 4 Jul 2011 12:33:54 -0300 Subject: [media] DiB8000: improve the tuning and the SNR monitoring This patches improves the tuning of the dib8000 and correct the monitoringr of the SNR.The patch allows to faster detect that there is no ISDB-T channel on the wanted frequency. Signed-off-by: Olivier Grenie Signed-off-by: Patrick Boettcher Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/dvb/frontends/dib8000.c b/drivers/media/dvb/frontends/dib8000.c index fe284d5..96c6a61 100644 --- a/drivers/media/dvb/frontends/dib8000.c +++ b/drivers/media/dvb/frontends/dib8000.c @@ -2215,7 +2215,7 @@ static int dib8000_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_par ((state->fe[0]->dtv_property_cache.layer[1].segment_count == 0) || ((state->fe[0]->dtv_property_cache.isdbt_layer_enabled & (2 << 0)) == 0)) && ((state->fe[0]->dtv_property_cache.layer[2].segment_count == 0) || ((state->fe[0]->dtv_property_cache.isdbt_layer_enabled & (3 << 0)) == 0)))) { - int i = 80000; + int i = 100; u8 found = 0; u8 tune_failed = 0; @@ -2243,6 +2243,7 @@ static int dib8000_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_par default: dprintk("unhandled autosearch result"); case 1: + tune_failed |= (1 << index_frontend); dprintk("autosearch failed for the frontend%i", index_frontend); break; } @@ -2401,7 +2402,7 @@ static int dib8000_read_snr(struct dvb_frontend *fe, u16 * snr) for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) snr_master += dib8000_get_snr(state->fe[index_frontend]); - if (snr_master != 0) { + if ((snr_master >> 16) != 0) { snr_master = 10*intlog10(snr_master>>16); *snr = snr_master / ((1 << 24) / 10); } -- cgit v0.10.2 From b293f304c52c4e7a3473dad4d4d0f3bc3c3cd32f Mon Sep 17 00:00:00 2001 From: Olivier Grenie Date: Tue, 9 Aug 2011 04:48:25 -0300 Subject: [media] dib7090: add the reference board TFE7790E The intend of this patch is to add the support for the DiBcom reference board TFE7790E. Signed-off-by: Olivier Grenie Signed-off-by: Patrick Boettcher Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/dvb/dvb-usb/dib0700_devices.c b/drivers/media/dvb/dvb-usb/dib0700_devices.c index d82740a..845b11a 100644 --- a/drivers/media/dvb/dvb-usb/dib0700_devices.c +++ b/drivers/media/dvb/dvb-usb/dib0700_devices.c @@ -2428,6 +2428,71 @@ static const struct dib0090_config tfe7090e_dib0090_config = { .is_dib7090e = 1, }; +static struct dib7000p_config tfe7790e_dib7000p_config = { + .output_mpeg2_in_188_bytes = 1, + .hostbus_diversity = 1, + .tuner_is_baseband = 1, + .update_lna = dib7090e_update_lna, + + .agc_config_count = 2, + .agc = dib7090_agc_config, + + .bw = &dib7090_clock_config_12_mhz, + + .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS, + .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES, + .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS, + + .pwm_freq_div = 0, + + .agc_control = dib7090_agc_restart, + + .spur_protect = 0, + .disable_sample_and_hold = 0, + .enable_current_mirror = 0, + .diversity_delay = 0, + + .output_mode = OUTMODE_MPEG2_PAR_GATED_CLK, + .enMpegOutput = 1, +}; + +static const struct dib0090_config tfe7790e_dib0090_config = { + .io.clock_khz = 12000, + .io.pll_bypass = 0, + .io.pll_range = 0, + .io.pll_prediv = 3, + .io.pll_loopdiv = 6, + .io.adc_clock_ratio = 0, + .io.pll_int_loop_filt = 0, + .reset = dib7090_tuner_sleep, + .sleep = dib7090_tuner_sleep, + + .freq_offset_khz_uhf = 0, + .freq_offset_khz_vhf = 0, + + .get_adc_power = dib7090_get_adc_power, + + .clkouttobamse = 1, + .analog_output = 0, + + .wbd_vhf_offset = 0, + .wbd_cband_offset = 0, + .use_pwm_agc = 1, + .clkoutdrive = 0, + + .fref_clock_ratio = 0, + + .wbd = dib7090e_wbd_table, + + .ls_cfg_pad_drv = 0, + .data_tx_drv = 0, + .low_if = NULL, + .in_soc = 1, + .force_cband_input = 1, + .is_dib7090e = 1, + .force_crystal_mode = 1, +}; + static const struct dib0090_config tfe7090pvr_dib0090_config[2] = { { .io.clock_khz = 12000, @@ -2646,6 +2711,54 @@ static int tfe7090e_frontend_attach(struct dvb_usb_adapter *adap) return adap->fe_adap[0].fe == NULL ? -ENODEV : 0; } +static int tfe7790e_frontend_attach(struct dvb_usb_adapter *adap) +{ + struct dib0700_state *st = adap->dev->priv; + + /* The TFE7790E requires the dib0700 to not be in master mode */ + st->disable_streaming_master_mode = 1; + + dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1); + msleep(20); + dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1); + dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1); + dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1); + dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0); + msleep(20); + dib0700_ctrl_clock(adap->dev, 72, 1); + dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1); + msleep(20); + dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1); + + if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, + 1, 0x10, &tfe7790e_dib7000p_config) != 0) { + err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n", + __func__); + return -ENODEV; + } + adap->fe_adap[0].fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, + 0x80, &tfe7790e_dib7000p_config); + + return adap->fe_adap[0].fe == NULL ? -ENODEV : 0; +} + +static int tfe7790e_tuner_attach(struct dvb_usb_adapter *adap) +{ + struct dib0700_adapter_state *st = adap->priv; + struct i2c_adapter *tun_i2c = + dib7090_get_i2c_tuner(adap->fe_adap[0].fe); + + if (dvb_attach(dib0090_register, adap->fe_adap[0].fe, tun_i2c, + &tfe7790e_dib0090_config) == NULL) + return -ENODEV; + + dib7000p_set_gpio(adap->fe_adap[0].fe, 8, 0, 1); + + st->set_param_save = adap->fe_adap[0].fe->ops.tuner_ops.set_params; + adap->fe_adap[0].fe->ops.tuner_ops.set_params = dib7090_agc_startup; + return 0; +} + static int tfe7090e_tuner_attach(struct dvb_usb_adapter *adap) { struct dib0700_adapter_state *st = adap->priv; @@ -3120,6 +3233,7 @@ struct usb_device_id dib0700_usb_id_table[] = { { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV340E) }, { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV340E_SE) }, { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_TFE7090E) }, + { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_TFE7790E) }, { 0 } /* Terminating entry */ }; MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table); @@ -4225,6 +4339,46 @@ struct dvb_usb_device_properties dib0700_devices[] = { RC_TYPE_NEC, .change_protocol = dib0700_change_protocol, }, + }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, + .num_adapters = 1, + .adapter = { + { + .num_frontends = 1, + .fe = {{ + .caps = DVB_USB_ADAP_HAS_PID_FILTER | + DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, + .pid_filter_count = 32, + .pid_filter = stk70x0p_pid_filter, + .pid_filter_ctrl = stk70x0p_pid_filter_ctrl, + .frontend_attach = tfe7790e_frontend_attach, + .tuner_attach = tfe7790e_tuner_attach, + + DIB0700_DEFAULT_STREAMING_CONFIG(0x03), + } }, + + .size_of_priv = + sizeof(struct dib0700_adapter_state), + }, + }, + + .num_device_descs = 1, + .devices = { + { "DiBcom TFE7790E reference design", + { &dib0700_usb_id_table[79], NULL }, + { NULL }, + }, + }, + + .rc.core = { + .rc_interval = DEFAULT_RC_INTERVAL, + .rc_codes = RC_MAP_DIB0700_RC5_TABLE, + .module_name = "dib0700", + .rc_query = dib0700_rc_query_old_firmware, + .allowed_protos = RC_TYPE_RC5 | + RC_TYPE_RC6 | + RC_TYPE_NEC, + .change_protocol = dib0700_change_protocol, + }, }, }; diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h index 908a616..3f437eb 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h +++ b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h @@ -114,6 +114,7 @@ #define USB_PID_DIBCOM_NIM7090 0x1bb2 #define USB_PID_DIBCOM_TFE7090PVR 0x1bb4 #define USB_PID_DIBCOM_TFE7090E 0x1bb7 +#define USB_PID_DIBCOM_TFE7790E 0x1e6e #define USB_PID_DIBCOM_NIM9090M 0x2383 #define USB_PID_DIBCOM_NIM9090MD 0x2384 #define USB_PID_DPOSH_M9206_COLD 0x9206 -- cgit v0.10.2 From 0c32dbd74fa947a922b9df125ac8795ce761fa8a Mon Sep 17 00:00:00 2001 From: Olivier Grenie Date: Wed, 10 Aug 2011 05:17:18 -0300 Subject: [media] add the support for DiBcom dib8096P The purpose of this patch is to support the DiBcom chip dib8096P. Signed-off-by: Olivier Grenie Signed-off-by: Patrick Boettcher Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/dvb/dvb-usb/dib0700_devices.c b/drivers/media/dvb/dvb-usb/dib0700_devices.c index 845b11a..b7b4b65 100644 --- a/drivers/media/dvb/dvb-usb/dib0700_devices.c +++ b/drivers/media/dvb/dvb-usb/dib0700_devices.c @@ -1279,7 +1279,7 @@ static int stk807x_frontend_attach(struct dvb_usb_adapter *adap) dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1); dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 18, - 0x80); + 0x80, 0); adap->fe_adap[0].fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x80, &dib807x_dib8000_config[0]); @@ -1308,7 +1308,7 @@ static int stk807xpvr_frontend_attach0(struct dvb_usb_adapter *adap) dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1); /* initialize IC 0 */ - dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x22, 0x80); + dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x22, 0x80, 0); adap->fe_adap[0].fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x80, &dib807x_dib8000_config[0]); @@ -1319,7 +1319,7 @@ static int stk807xpvr_frontend_attach0(struct dvb_usb_adapter *adap) static int stk807xpvr_frontend_attach1(struct dvb_usb_adapter *adap) { /* initialize IC 1 */ - dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x12, 0x82); + dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x12, 0x82, 0); adap->fe_adap[0].fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x82, &dib807x_dib8000_config[1]); @@ -1578,7 +1578,7 @@ static int stk809x_frontend_attach(struct dvb_usb_adapter *adap) msleep(10); dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1); - dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 18, 0x80); + dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 18, 0x80, 0); adap->fe_adap[0].fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x80, &dib809x_dib8000_config[0]); @@ -1629,7 +1629,7 @@ static int nim8096md_frontend_attach(struct dvb_usb_adapter *adap) msleep(20); dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1); - dib8000_i2c_enumeration(&adap->dev->i2c_adap, 2, 18, 0x80); + dib8000_i2c_enumeration(&adap->dev->i2c_adap, 2, 18, 0x80, 0); adap->fe_adap[0].fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x80, &dib809x_dib8000_config[0]); if (adap->fe_adap[0].fe == NULL) diff --git a/drivers/media/dvb/frontends/dib7000p.c b/drivers/media/dvb/frontends/dib7000p.c index 3ab695b..b5f3fb4 100644 --- a/drivers/media/dvb/frontends/dib7000p.c +++ b/drivers/media/dvb/frontends/dib7000p.c @@ -81,13 +81,6 @@ enum dib7000p_power_mode { }; /* dib7090 specific fonctions */ -#define MPEG_ON_DIBTX 1 -#define DIV_ON_DIBTX 2 -#define ADC_ON_DIBTX 3 -#define DEMOUT_ON_HOSTBUS 4 -#define DIBTX_ON_HOSTBUS 5 -#define MPEG_ON_HOSTBUS 6 - static int dib7090_set_output_mode(struct dvb_frontend *fe, int mode); static int dib7090_set_diversity_in(struct dvb_frontend *fe, int onoff); static void dib7090_setDibTxMux(struct dib7000p_state *state, int mode); diff --git a/drivers/media/dvb/frontends/dib8000.c b/drivers/media/dvb/frontends/dib8000.c index 96c6a61..b8da0c9 100644 --- a/drivers/media/dvb/frontends/dib8000.c +++ b/drivers/media/dvb/frontends/dib8000.c @@ -81,11 +81,15 @@ struct dib8000_state { u8 i2c_write_buffer[4]; u8 i2c_read_buffer[2]; struct mutex i2c_buffer_lock; + u8 input_mode_mpeg; + + u16 tuner_enable; + struct i2c_adapter dib8096p_tuner_adap; }; enum dib8000_power_mode { - DIB8000M_POWER_ALL = 0, - DIB8000M_POWER_INTERFACE_ONLY, + DIB8000_POWER_ALL = 0, + DIB8000_POWER_INTERFACE_ONLY, }; static u16 dib8000_i2c_read16(struct i2c_device *i2c, u16 reg) @@ -428,20 +432,31 @@ static void dib8000_set_power_mode(struct dib8000_state *state, enum dib8000_pow /* by default everything is going to be powered off */ u16 reg_774 = 0x3fff, reg_775 = 0xffff, reg_776 = 0xffff, reg_900 = (dib8000_read_word(state, 900) & 0xfffc) | 0x3, + reg_1280; + + if (state->revision != 0x8090) reg_1280 = (dib8000_read_word(state, 1280) & 0x00ff) | 0xff00; + else + reg_1280 = (dib8000_read_word(state, 1280) & 0x707f) | 0x8f80; /* now, depending on the requested mode, we power on */ switch (mode) { /* power up everything in the demod */ - case DIB8000M_POWER_ALL: + case DIB8000_POWER_ALL: reg_774 = 0x0000; reg_775 = 0x0000; reg_776 = 0x0000; reg_900 &= 0xfffc; - reg_1280 &= 0x00ff; + if (state->revision != 0x8090) + reg_1280 &= 0x00ff; + else + reg_1280 &= 0x707f; break; - case DIB8000M_POWER_INTERFACE_ONLY: - reg_1280 &= 0x00ff; + case DIB8000_POWER_INTERFACE_ONLY: + if (state->revision != 0x8090) + reg_1280 &= 0x00ff; + else + reg_1280 &= 0xfa7b; break; } @@ -453,19 +468,67 @@ static void dib8000_set_power_mode(struct dib8000_state *state, enum dib8000_pow dib8000_write_word(state, 1280, reg_1280); } +static int dib8000_init_sdram(struct dib8000_state *state) +{ + u16 reg = 0; + dprintk("Init sdram"); + + reg = dib8000_read_word(state, 274)&0xfff0; + /* P_dintlv_delay_ram = 7 because of MobileSdram */ + dib8000_write_word(state, 274, reg | 0x7); + + dib8000_write_word(state, 1803, (7<<2)); + + reg = dib8000_read_word(state, 1280); + /* force restart P_restart_sdram */ + dib8000_write_word(state, 1280, reg | (1<<2)); + + /* release restart P_restart_sdram */ + dib8000_write_word(state, 1280, reg); + + return 0; +} + static int dib8000_set_adc_state(struct dib8000_state *state, enum dibx000_adc_states no) { int ret = 0; - u16 reg_907 = dib8000_read_word(state, 907), reg_908 = dib8000_read_word(state, 908); + u16 reg, reg_907 = dib8000_read_word(state, 907); + u16 reg_908 = dib8000_read_word(state, 908); switch (no) { case DIBX000_SLOW_ADC_ON: - reg_908 |= (1 << 1) | (1 << 0); - ret |= dib8000_write_word(state, 908, reg_908); - reg_908 &= ~(1 << 1); + if (state->revision != 0x8090) { + reg_908 |= (1 << 1) | (1 << 0); + ret |= dib8000_write_word(state, 908, reg_908); + reg_908 &= ~(1 << 1); + } else { + reg = dib8000_read_word(state, 1925); + /* en_slowAdc = 1 & reset_sladc = 1 */ + dib8000_write_word(state, 1925, reg | + (1<<4) | (1<<2)); + + /* read acces to make it works... strange ... */ + reg = dib8000_read_word(state, 1925); + msleep(20); + /* en_slowAdc = 1 & reset_sladc = 0 */ + dib8000_write_word(state, 1925, reg & ~(1<<4)); + + reg = dib8000_read_word(state, 921) & ~((0x3 << 14) + | (0x3 << 12)); + /* ref = Vin1 => Vbg ; sel = Vin0 or Vin3 ; + (Vin2 = Vcm) */ + dib8000_write_word(state, 921, reg | (1 << 14) + | (3 << 12)); + } break; case DIBX000_SLOW_ADC_OFF: + if (state->revision == 0x8090) { + reg = dib8000_read_word(state, 1925); + /* reset_sladc = 1 en_slowAdc = 0 */ + dib8000_write_word(state, 1925, + (reg & ~(1<<2)) | (1<<4)); + } reg_908 |= (1 << 1) | (1 << 0); break; @@ -521,7 +584,12 @@ static int dib8000_set_bandwidth(struct dvb_frontend *fe, u32 bw) static int dib8000_sad_calib(struct dib8000_state *state) { -/* internal */ + if (state->revision == 0x8090) { + dprintk("%s: the sad calibration is not needed for the dib8096P", + __func__); + return 0; + } + /* internal */ dib8000_write_word(state, 923, (0 << 1) | (0 << 0)); dib8000_write_word(state, 924, 776); // 0.625*3.3 / 4096 @@ -546,48 +614,129 @@ EXPORT_SYMBOL(dib8000_set_wbd_ref); static void dib8000_reset_pll_common(struct dib8000_state *state, const struct dibx000_bandwidth_config *bw) { dprintk("ifreq: %d %x, inversion: %d", bw->ifreq, bw->ifreq, bw->ifreq >> 25); - dib8000_write_word(state, 23, (u16) (((bw->internal * 1000) >> 16) & 0xffff)); /* P_sec_len */ - dib8000_write_word(state, 24, (u16) ((bw->internal * 1000) & 0xffff)); + if (state->revision != 0x8090) { + dib8000_write_word(state, 23, + (u16) (((bw->internal * 1000) >> 16) & 0xffff)); + dib8000_write_word(state, 24, + (u16) ((bw->internal * 1000) & 0xffff)); + } else { + dib8000_write_word(state, 23, (u16) (((bw->internal / 2 * 1000) >> 16) & 0xffff)); + dib8000_write_word(state, 24, + (u16) ((bw->internal / 2 * 1000) & 0xffff)); + } dib8000_write_word(state, 27, (u16) ((bw->ifreq >> 16) & 0x01ff)); dib8000_write_word(state, 28, (u16) (bw->ifreq & 0xffff)); dib8000_write_word(state, 26, (u16) ((bw->ifreq >> 25) & 0x0003)); - dib8000_write_word(state, 922, bw->sad_cfg); + if (state->revision != 0x8090) + dib8000_write_word(state, 922, bw->sad_cfg); } static void dib8000_reset_pll(struct dib8000_state *state) { const struct dibx000_bandwidth_config *pll = state->cfg.pll; - u16 clk_cfg1; - - // clk_cfg0 - dib8000_write_word(state, 901, (pll->pll_prediv << 8) | (pll->pll_ratio << 0)); - - // clk_cfg1 - clk_cfg1 = (1 << 10) | (0 << 9) | (pll->IO_CLK_en_core << 8) | - (pll->bypclk_div << 5) | (pll->enable_refdiv << 4) | (1 << 3) | - (pll->pll_range << 1) | (pll->pll_reset << 0); - - dib8000_write_word(state, 902, clk_cfg1); - clk_cfg1 = (clk_cfg1 & 0xfff7) | (pll->pll_bypass << 3); - dib8000_write_word(state, 902, clk_cfg1); - - dprintk("clk_cfg1: 0x%04x", clk_cfg1); /* 0x507 1 0 1 000 0 0 11 1 */ - - /* smpl_cfg: P_refclksel=2, P_ensmplsel=1 nodivsmpl=1 */ - if (state->cfg.pll->ADClkSrc == 0) - dib8000_write_word(state, 904, (0 << 15) | (0 << 12) | (0 << 10) | - (pll->modulo << 8) | (pll->ADClkSrc << 7) | (0 << 1)); - else if (state->cfg.refclksel != 0) - dib8000_write_word(state, 904, (0 << 15) | (1 << 12) | - ((state->cfg.refclksel & 0x3) << 10) | (pll->modulo << 8) | - (pll->ADClkSrc << 7) | (0 << 1)); - else - dib8000_write_word(state, 904, (0 << 15) | (1 << 12) | (3 << 10) | (pll->modulo << 8) | (pll->ADClkSrc << 7) | (0 << 1)); + u16 clk_cfg1, reg; + + if (state->revision != 0x8090) { + dib8000_write_word(state, 901, + (pll->pll_prediv << 8) | (pll->pll_ratio << 0)); + + clk_cfg1 = (1 << 10) | (0 << 9) | (pll->IO_CLK_en_core << 8) | + (pll->bypclk_div << 5) | (pll->enable_refdiv << 4) | + (1 << 3) | (pll->pll_range << 1) | + (pll->pll_reset << 0); + + dib8000_write_word(state, 902, clk_cfg1); + clk_cfg1 = (clk_cfg1 & 0xfff7) | (pll->pll_bypass << 3); + dib8000_write_word(state, 902, clk_cfg1); + + dprintk("clk_cfg1: 0x%04x", clk_cfg1); + + /* smpl_cfg: P_refclksel=2, P_ensmplsel=1 nodivsmpl=1 */ + if (state->cfg.pll->ADClkSrc == 0) + dib8000_write_word(state, 904, + (0 << 15) | (0 << 12) | (0 << 10) | + (pll->modulo << 8) | + (pll->ADClkSrc << 7) | (0 << 1)); + else if (state->cfg.refclksel != 0) + dib8000_write_word(state, 904, (0 << 15) | (1 << 12) | + ((state->cfg.refclksel & 0x3) << 10) | + (pll->modulo << 8) | + (pll->ADClkSrc << 7) | (0 << 1)); + else + dib8000_write_word(state, 904, (0 << 15) | (1 << 12) | + (3 << 10) | (pll->modulo << 8) | + (pll->ADClkSrc << 7) | (0 << 1)); + } else { + dib8000_write_word(state, 1856, (!pll->pll_reset<<13) | + (pll->pll_range<<12) | (pll->pll_ratio<<6) | + (pll->pll_prediv)); + + reg = dib8000_read_word(state, 1857); + dib8000_write_word(state, 1857, reg|(!pll->pll_bypass<<15)); + + reg = dib8000_read_word(state, 1858); /* Force clk out pll /2 */ + dib8000_write_word(state, 1858, reg | 1); + + dib8000_write_word(state, 904, (pll->modulo << 8)); + } dib8000_reset_pll_common(state, pll); } +int dib8000_update_pll(struct dvb_frontend *fe, + struct dibx000_bandwidth_config *pll) +{ + struct dib8000_state *state = fe->demodulator_priv; + u16 reg_1857, reg_1856 = dib8000_read_word(state, 1856); + u8 loopdiv, prediv; + u32 internal, xtal; + + /* get back old values */ + prediv = reg_1856 & 0x3f; + loopdiv = (reg_1856 >> 6) & 0x3f; + + if ((pll != NULL) && (pll->pll_prediv != prediv || + pll->pll_ratio != loopdiv)) { + dprintk("Updating pll (prediv: old = %d new = %d ; loopdiv : old = %d new = %d)", prediv, pll->pll_prediv, loopdiv, pll->pll_ratio); + reg_1856 &= 0xf000; + reg_1857 = dib8000_read_word(state, 1857); + /* disable PLL */ + dib8000_write_word(state, 1857, reg_1857 & ~(1 << 15)); + + dib8000_write_word(state, 1856, reg_1856 | + ((pll->pll_ratio & 0x3f) << 6) | + (pll->pll_prediv & 0x3f)); + + /* write new system clk into P_sec_len */ + internal = dib8000_read32(state, 23) / 1000; + dprintk("Old Internal = %d", internal); + xtal = 2 * (internal / loopdiv) * prediv; + internal = 1000 * (xtal/pll->pll_prediv) * pll->pll_ratio; + dprintk("Xtal = %d , New Fmem = %d New Fdemod = %d, New Fsampling = %d", xtal, internal/1000, internal/2000, internal/8000); + dprintk("New Internal = %d", internal); + + dib8000_write_word(state, 23, + (u16) (((internal / 2) >> 16) & 0xffff)); + dib8000_write_word(state, 24, (u16) ((internal / 2) & 0xffff)); + /* enable PLL */ + dib8000_write_word(state, 1857, reg_1857 | (1 << 15)); + + while (((dib8000_read_word(state, 1856)>>15)&0x1) != 1) + dprintk("Waiting for PLL to lock"); + + /* verify */ + reg_1856 = dib8000_read_word(state, 1856); + dprintk("PLL Updated with prediv = %d and loopdiv = %d", + reg_1856&0x3f, (reg_1856>>6)&0x3f); + + return 0; + } + return -EINVAL; +} +EXPORT_SYMBOL(dib8000_update_pll); + + static int dib8000_reset_gpio(struct dib8000_state *st) { /* reset the GPIOs */ @@ -721,9 +870,6 @@ static const u16 dib8000_defaults[] = { (3 << 5) | /* P_ctrl_pre_freq_step=3 */ (1 << 0), /* P_pre_freq_win_len=1 */ - 1, 903, - (0 << 4) | 2, // P_divclksel=0 P_divbitsel=2 (was clk=3,bit=1 for MPW) - 0, }; @@ -740,7 +886,8 @@ static u16 dib8000_identify(struct i2c_device *client) } value = dib8000_i2c_read16(client, 897); - if (value != 0x8000 && value != 0x8001 && value != 0x8002) { + if (value != 0x8000 && value != 0x8001 && + value != 0x8002 && value != 0x8090) { dprintk("wrong Device ID (%x)", value); return 0; } @@ -755,6 +902,9 @@ static u16 dib8000_identify(struct i2c_device *client) case 0x8002: dprintk("found DiB8000C"); break; + case 0x8090: + dprintk("found DiB8096P"); + break; } return value; } @@ -763,17 +913,19 @@ static int dib8000_reset(struct dvb_frontend *fe) { struct dib8000_state *state = fe->demodulator_priv; - dib8000_write_word(state, 1287, 0x0003); /* sram lead in, rdy */ - if ((state->revision = dib8000_identify(&state->i2c)) == 0) return -EINVAL; + /* sram lead in, rdy */ + if (state->revision != 0x8090) + dib8000_write_word(state, 1287, 0x0003); + if (state->revision == 0x8000) dprintk("error : dib8000 MA not supported"); dibx000_reset_i2c_master(&state->i2c_master); - dib8000_set_power_mode(state, DIB8000M_POWER_ALL); + dib8000_set_power_mode(state, DIB8000_POWER_ALL); /* always leave the VBG voltage on - it consumes almost nothing but takes a long time to start */ dib8000_set_adc_state(state, DIBX000_VBG_ENABLE); @@ -782,8 +934,10 @@ static int dib8000_reset(struct dvb_frontend *fe) dib8000_write_word(state, 770, 0xffff); dib8000_write_word(state, 771, 0xffff); dib8000_write_word(state, 772, 0xfffc); - dib8000_write_word(state, 898, 0x000c); // sad - dib8000_write_word(state, 1280, 0x004d); + if (state->revision == 0x8090) + dib8000_write_word(state, 1280, 0x0045); + else + dib8000_write_word(state, 1280, 0x004d); dib8000_write_word(state, 1281, 0x000c); dib8000_write_word(state, 770, 0x0000); @@ -794,19 +948,25 @@ static int dib8000_reset(struct dvb_frontend *fe) dib8000_write_word(state, 1281, 0x0000); /* drives */ - if (state->cfg.drives) - dib8000_write_word(state, 906, state->cfg.drives); - else { - dprintk("using standard PAD-drive-settings, please adjust settings in config-struct to be optimal."); - dib8000_write_word(state, 906, 0x2d98); // min drive SDRAM - not optimal - adjust + if (state->revision != 0x8090) { + if (state->cfg.drives) + dib8000_write_word(state, 906, state->cfg.drives); + else { + dprintk("using standard PAD-drive-settings, please adjust settings in config-struct to be optimal."); + /* min drive SDRAM - not optimal - adjust */ + dib8000_write_word(state, 906, 0x2d98); + } } dib8000_reset_pll(state); + if (state->revision != 0x8090) + dib8000_write_word(state, 898, 0x0004); if (dib8000_reset_gpio(state) != 0) dprintk("GPIO reset was not successful."); - if (dib8000_set_output_mode(fe, OUTMODE_HIGH_Z) != 0) + if ((state->revision != 0x8090) && + (dib8000_set_output_mode(fe, OUTMODE_HIGH_Z) != 0)) dprintk("OUTPUT_MODE could not be resetted."); state->current_agc = NULL; @@ -832,6 +992,8 @@ static int dib8000_reset(struct dvb_frontend *fe) l = *n++; } } + if (state->revision != 0x8090) + dib8000_write_word(state, 903, (0 << 4) | 2); state->isdbt_cfg_loaded = 0; //div_cfg override for special configs @@ -844,10 +1006,12 @@ static int dib8000_reset(struct dvb_frontend *fe) dib8000_set_bandwidth(fe, 6000); dib8000_set_adc_state(state, DIBX000_SLOW_ADC_ON); - dib8000_sad_calib(state); - dib8000_set_adc_state(state, DIBX000_SLOW_ADC_OFF); + if (state->revision != 0x8090) { + dib8000_sad_calib(state); + dib8000_set_adc_state(state, DIBX000_SLOW_ADC_OFF); + } - dib8000_set_power_mode(state, DIB8000M_POWER_INTERFACE_ONLY); + dib8000_set_power_mode(state, DIB8000_POWER_INTERFACE_ONLY); return 0; } @@ -879,6 +1043,8 @@ static int dib8000_set_agc_config(struct dib8000_state *state, u8 band) { struct dibx000_agc_config *agc = NULL; int i; + u16 reg; + if (state->current_band == band && state->current_agc != NULL) return 0; state->current_band = band; @@ -914,6 +1080,12 @@ static int dib8000_set_agc_config(struct dib8000_state *state, u8 band) dib8000_write_word(state, 106, state->wbd_ref); else // use default dib8000_write_word(state, 106, agc->wbd_ref); + + if (state->revision == 0x8090) { + reg = dib8000_read_word(state, 922) & (0x3 << 2); + dib8000_write_word(state, 922, reg | (agc->wbd_sel << 2)); + } + dib8000_write_word(state, 107, (agc->wbd_alpha << 9) | (agc->perform_agc_softsplit << 8)); dib8000_write_word(state, 108, agc->agc1_max); dib8000_write_word(state, 109, agc->agc1_min); @@ -925,7 +1097,10 @@ static int dib8000_set_agc_config(struct dib8000_state *state, u8 band) dib8000_write_word(state, 115, (agc->agc2_slope1 << 8) | agc->agc2_slope2); dib8000_write_word(state, 75, agc->agc1_pt3); - dib8000_write_word(state, 923, (dib8000_read_word(state, 923) & 0xffe3) | (agc->wbd_inv << 4) | (agc->wbd_sel << 2)); /*LB : 929 -> 923 */ + if (state->revision != 0x8090) + dib8000_write_word(state, 923, + (dib8000_read_word(state, 923) & 0xffe3) | + (agc->wbd_inv << 4) | (agc->wbd_sel << 2)); return 0; } @@ -968,14 +1143,30 @@ static int dib8000_agc_startup(struct dvb_frontend *fe) { struct dib8000_state *state = fe->demodulator_priv; enum frontend_tune_state *tune_state = &state->tune_state; - int ret = 0; + u16 reg, upd_demod_gain_period = 0x8000; switch (*tune_state) { case CT_AGC_START: // set power-up level: interf+analog+AGC - dib8000_set_adc_state(state, DIBX000_ADC_ON); + if (state->revision != 0x8090) + dib8000_set_adc_state(state, DIBX000_ADC_ON); + else { + dib8000_set_power_mode(state, DIB8000_POWER_ALL); + + reg = dib8000_read_word(state, 1947)&0xff00; + dib8000_write_word(state, 1946, + upd_demod_gain_period & 0xFFFF); + /* bit 14 = enDemodGain */ + dib8000_write_word(state, 1947, reg | (1<<14) | + ((upd_demod_gain_period >> 16) & 0xFF)); + + /* enable adc i & q */ + reg = dib8000_read_word(state, 1920); + dib8000_write_word(state, 1920, (reg | 0x3) & + (~(1 << 7))); + } if (dib8000_set_agc_config(state, (unsigned char)(BAND_OF_FREQUENCY(fe->dtv_property_cache.frequency / 1000))) != 0) { *tune_state = CT_AGC_STOP; @@ -1026,6 +1217,579 @@ static int dib8000_agc_startup(struct dvb_frontend *fe) } +static void dib8096p_host_bus_drive(struct dib8000_state *state, u8 drive) +{ + u16 reg; + + drive &= 0x7; + + /* drive host bus 2, 3, 4 */ + reg = dib8000_read_word(state, 1798) & + ~(0x7 | (0x7 << 6) | (0x7 << 12)); + reg |= (drive<<12) | (drive<<6) | drive; + dib8000_write_word(state, 1798, reg); + + /* drive host bus 5,6 */ + reg = dib8000_read_word(state, 1799) & ~((0x7 << 2) | (0x7 << 8)); + reg |= (drive<<8) | (drive<<2); + dib8000_write_word(state, 1799, reg); + + /* drive host bus 7, 8, 9 */ + reg = dib8000_read_word(state, 1800) & + ~(0x7 | (0x7 << 6) | (0x7 << 12)); + reg |= (drive<<12) | (drive<<6) | drive; + dib8000_write_word(state, 1800, reg); + + /* drive host bus 10, 11 */ + reg = dib8000_read_word(state, 1801) & ~((0x7 << 2) | (0x7 << 8)); + reg |= (drive<<8) | (drive<<2); + dib8000_write_word(state, 1801, reg); + + /* drive host bus 12, 13, 14 */ + reg = dib8000_read_word(state, 1802) & + ~(0x7 | (0x7 << 6) | (0x7 << 12)); + reg |= (drive<<12) | (drive<<6) | drive; + dib8000_write_word(state, 1802, reg); +} + +static u32 dib8096p_calcSyncFreq(u32 P_Kin, u32 P_Kout, + u32 insertExtSynchro, u32 syncSize) +{ + u32 quantif = 3; + u32 nom = (insertExtSynchro * P_Kin+syncSize); + u32 denom = P_Kout; + u32 syncFreq = ((nom << quantif) / denom); + + if ((syncFreq & ((1 << quantif) - 1)) != 0) + syncFreq = (syncFreq >> quantif) + 1; + else + syncFreq = (syncFreq >> quantif); + + if (syncFreq != 0) + syncFreq = syncFreq - 1; + + return syncFreq; +} + +static void dib8096p_cfg_DibTx(struct dib8000_state *state, u32 P_Kin, + u32 P_Kout, u32 insertExtSynchro, u32 synchroMode, + u32 syncWord, u32 syncSize) +{ + dprintk("Configure DibStream Tx"); + + dib8000_write_word(state, 1615, 1); + dib8000_write_word(state, 1603, P_Kin); + dib8000_write_word(state, 1605, P_Kout); + dib8000_write_word(state, 1606, insertExtSynchro); + dib8000_write_word(state, 1608, synchroMode); + dib8000_write_word(state, 1609, (syncWord >> 16) & 0xffff); + dib8000_write_word(state, 1610, syncWord & 0xffff); + dib8000_write_word(state, 1612, syncSize); + dib8000_write_word(state, 1615, 0); +} + +static void dib8096p_cfg_DibRx(struct dib8000_state *state, u32 P_Kin, + u32 P_Kout, u32 synchroMode, u32 insertExtSynchro, + u32 syncWord, u32 syncSize, u32 dataOutRate) +{ + u32 syncFreq; + + dprintk("Configure DibStream Rx synchroMode = %d", synchroMode); + + if ((P_Kin != 0) && (P_Kout != 0)) { + syncFreq = dib8096p_calcSyncFreq(P_Kin, P_Kout, + insertExtSynchro, syncSize); + dib8000_write_word(state, 1542, syncFreq); + } + + dib8000_write_word(state, 1554, 1); + dib8000_write_word(state, 1536, P_Kin); + dib8000_write_word(state, 1537, P_Kout); + dib8000_write_word(state, 1539, synchroMode); + dib8000_write_word(state, 1540, (syncWord >> 16) & 0xffff); + dib8000_write_word(state, 1541, syncWord & 0xffff); + dib8000_write_word(state, 1543, syncSize); + dib8000_write_word(state, 1544, dataOutRate); + dib8000_write_word(state, 1554, 0); +} + +static void dib8096p_enMpegMux(struct dib8000_state *state, int onoff) +{ + u16 reg_1287; + + reg_1287 = dib8000_read_word(state, 1287); + + switch (onoff) { + case 1: + reg_1287 &= ~(1 << 8); + break; + case 0: + reg_1287 |= (1 << 8); + break; + } + + dib8000_write_word(state, 1287, reg_1287); +} + +static void dib8096p_configMpegMux(struct dib8000_state *state, + u16 pulseWidth, u16 enSerialMode, u16 enSerialClkDiv2) +{ + u16 reg_1287; + + dprintk("Enable Mpeg mux"); + + dib8096p_enMpegMux(state, 0); + + /* If the input mode is MPEG do not divide the serial clock */ + if ((enSerialMode == 1) && (state->input_mode_mpeg == 1)) + enSerialClkDiv2 = 0; + + reg_1287 = ((pulseWidth & 0x1f) << 3) | + ((enSerialMode & 0x1) << 2) | (enSerialClkDiv2 & 0x1); + dib8000_write_word(state, 1287, reg_1287); + + dib8096p_enMpegMux(state, 1); +} + +static void dib8096p_setDibTxMux(struct dib8000_state *state, int mode) +{ + u16 reg_1288 = dib8000_read_word(state, 1288) & ~(0x7 << 7); + + switch (mode) { + case MPEG_ON_DIBTX: + dprintk("SET MPEG ON DIBSTREAM TX"); + dib8096p_cfg_DibTx(state, 8, 5, 0, 0, 0, 0); + reg_1288 |= (1 << 9); break; + case DIV_ON_DIBTX: + dprintk("SET DIV_OUT ON DIBSTREAM TX"); + dib8096p_cfg_DibTx(state, 5, 5, 0, 0, 0, 0); + reg_1288 |= (1 << 8); break; + case ADC_ON_DIBTX: + dprintk("SET ADC_OUT ON DIBSTREAM TX"); + dib8096p_cfg_DibTx(state, 20, 5, 10, 0, 0, 0); + reg_1288 |= (1 << 7); break; + default: + break; + } + dib8000_write_word(state, 1288, reg_1288); +} + +static void dib8096p_setHostBusMux(struct dib8000_state *state, int mode) +{ + u16 reg_1288 = dib8000_read_word(state, 1288) & ~(0x7 << 4); + + switch (mode) { + case DEMOUT_ON_HOSTBUS: + dprintk("SET DEM OUT OLD INTERF ON HOST BUS"); + dib8096p_enMpegMux(state, 0); + reg_1288 |= (1 << 6); + break; + case DIBTX_ON_HOSTBUS: + dprintk("SET DIBSTREAM TX ON HOST BUS"); + dib8096p_enMpegMux(state, 0); + reg_1288 |= (1 << 5); + break; + case MPEG_ON_HOSTBUS: + dprintk("SET MPEG MUX ON HOST BUS"); + reg_1288 |= (1 << 4); + break; + default: + break; + } + dib8000_write_word(state, 1288, reg_1288); +} + +static int dib8096p_set_diversity_in(struct dvb_frontend *fe, int onoff) +{ + struct dib8000_state *state = fe->demodulator_priv; + u16 reg_1287; + + switch (onoff) { + case 0: /* only use the internal way - not the diversity input */ + dprintk("%s mode OFF : by default Enable Mpeg INPUT", + __func__); + /* outputRate = 8 */ + dib8096p_cfg_DibRx(state, 8, 5, 0, 0, 0, 8, 0); + + /* Do not divide the serial clock of MPEG MUX in + SERIAL MODE in case input mode MPEG is used */ + reg_1287 = dib8000_read_word(state, 1287); + /* enSerialClkDiv2 == 1 ? */ + if ((reg_1287 & 0x1) == 1) { + /* force enSerialClkDiv2 = 0 */ + reg_1287 &= ~0x1; + dib8000_write_word(state, 1287, reg_1287); + } + state->input_mode_mpeg = 1; + break; + case 1: /* both ways */ + case 2: /* only the diversity input */ + dprintk("%s ON : Enable diversity INPUT", __func__); + dib8096p_cfg_DibRx(state, 5, 5, 0, 0, 0, 0, 0); + state->input_mode_mpeg = 0; + break; + } + + dib8000_set_diversity_in(state->fe[0], onoff); + return 0; +} + +static int dib8096p_set_output_mode(struct dvb_frontend *fe, int mode) +{ + struct dib8000_state *state = fe->demodulator_priv; + u16 outreg, smo_mode, fifo_threshold; + u8 prefer_mpeg_mux_use = 1; + int ret = 0; + + dib8096p_host_bus_drive(state, 1); + + fifo_threshold = 1792; + smo_mode = (dib8000_read_word(state, 299) & 0x0050) | (1 << 1); + outreg = dib8000_read_word(state, 1286) & + ~((1 << 10) | (0x7 << 6) | (1 << 1)); + + switch (mode) { + case OUTMODE_HIGH_Z: + outreg = 0; + break; + + case OUTMODE_MPEG2_SERIAL: + if (prefer_mpeg_mux_use) { + dprintk("dib8096P setting output mode TS_SERIAL using Mpeg Mux"); + dib8096p_configMpegMux(state, 3, 1, 1); + dib8096p_setHostBusMux(state, MPEG_ON_HOSTBUS); + } else {/* Use Smooth block */ + dprintk("dib8096P setting output mode TS_SERIAL using Smooth bloc"); + dib8096p_setHostBusMux(state, + DEMOUT_ON_HOSTBUS); + outreg |= (2 << 6) | (0 << 1); + } + break; + + case OUTMODE_MPEG2_PAR_GATED_CLK: + if (prefer_mpeg_mux_use) { + dprintk("dib8096P setting output mode TS_PARALLEL_GATED using Mpeg Mux"); + dib8096p_configMpegMux(state, 2, 0, 0); + dib8096p_setHostBusMux(state, MPEG_ON_HOSTBUS); + } else { /* Use Smooth block */ + dprintk("dib8096P setting output mode TS_PARALLEL_GATED using Smooth block"); + dib8096p_setHostBusMux(state, + DEMOUT_ON_HOSTBUS); + outreg |= (0 << 6); + } + break; + + case OUTMODE_MPEG2_PAR_CONT_CLK: /* Using Smooth block only */ + dprintk("dib8096P setting output mode TS_PARALLEL_CONT using Smooth block"); + dib8096p_setHostBusMux(state, DEMOUT_ON_HOSTBUS); + outreg |= (1 << 6); + break; + + case OUTMODE_MPEG2_FIFO: + /* Using Smooth block because not supported + by new Mpeg Mux bloc */ + dprintk("dib8096P setting output mode TS_FIFO using Smooth block"); + dib8096p_setHostBusMux(state, DEMOUT_ON_HOSTBUS); + outreg |= (5 << 6); + smo_mode |= (3 << 1); + fifo_threshold = 512; + break; + + case OUTMODE_DIVERSITY: + dprintk("dib8096P setting output mode MODE_DIVERSITY"); + dib8096p_setDibTxMux(state, DIV_ON_DIBTX); + dib8096p_setHostBusMux(state, DIBTX_ON_HOSTBUS); + break; + + case OUTMODE_ANALOG_ADC: + dprintk("dib8096P setting output mode MODE_ANALOG_ADC"); + dib8096p_setDibTxMux(state, ADC_ON_DIBTX); + dib8096p_setHostBusMux(state, DIBTX_ON_HOSTBUS); + break; + } + + if (mode != OUTMODE_HIGH_Z) + outreg |= (1<<10); + + dprintk("output_mpeg2_in_188_bytes = %d", + state->cfg.output_mpeg2_in_188_bytes); + if (state->cfg.output_mpeg2_in_188_bytes) + smo_mode |= (1 << 5); + + ret |= dib8000_write_word(state, 299, smo_mode); + /* synchronous fread */ + ret |= dib8000_write_word(state, 299 + 1, fifo_threshold); + ret |= dib8000_write_word(state, 1286, outreg); + + return ret; +} + +static int map_addr_to_serpar_number(struct i2c_msg *msg) +{ + if (msg->buf[0] <= 15) + msg->buf[0] -= 1; + else if (msg->buf[0] == 17) + msg->buf[0] = 15; + else if (msg->buf[0] == 16) + msg->buf[0] = 17; + else if (msg->buf[0] == 19) + msg->buf[0] = 16; + else if (msg->buf[0] >= 21 && msg->buf[0] <= 25) + msg->buf[0] -= 3; + else if (msg->buf[0] == 28) + msg->buf[0] = 23; + else if (msg->buf[0] == 99) + msg->buf[0] = 99; + else + return -EINVAL; + return 0; +} + +static int dib8096p_tuner_write_serpar(struct i2c_adapter *i2c_adap, + struct i2c_msg msg[], int num) +{ + struct dib8000_state *state = i2c_get_adapdata(i2c_adap); + u8 n_overflow = 1; + u16 i = 1000; + u16 serpar_num = msg[0].buf[0]; + + while (n_overflow == 1 && i) { + n_overflow = (dib8000_read_word(state, 1984) >> 1) & 0x1; + i--; + if (i == 0) + dprintk("Tuner ITF: write busy (overflow)"); + } + dib8000_write_word(state, 1985, (1 << 6) | (serpar_num & 0x3f)); + dib8000_write_word(state, 1986, (msg[0].buf[1] << 8) | msg[0].buf[2]); + + return num; +} + +static int dib8096p_tuner_read_serpar(struct i2c_adapter *i2c_adap, + struct i2c_msg msg[], int num) +{ + struct dib8000_state *state = i2c_get_adapdata(i2c_adap); + u8 n_overflow = 1, n_empty = 1; + u16 i = 1000; + u16 serpar_num = msg[0].buf[0]; + u16 read_word; + + while (n_overflow == 1 && i) { + n_overflow = (dib8000_read_word(state, 1984) >> 1) & 0x1; + i--; + if (i == 0) + dprintk("TunerITF: read busy (overflow)"); + } + dib8000_write_word(state, 1985, (0<<6) | (serpar_num&0x3f)); + + i = 1000; + while (n_empty == 1 && i) { + n_empty = dib8000_read_word(state, 1984)&0x1; + i--; + if (i == 0) + dprintk("TunerITF: read busy (empty)"); + } + + read_word = dib8000_read_word(state, 1987); + msg[1].buf[0] = (read_word >> 8) & 0xff; + msg[1].buf[1] = (read_word) & 0xff; + + return num; +} + +static int dib8096p_tuner_rw_serpar(struct i2c_adapter *i2c_adap, + struct i2c_msg msg[], int num) +{ + if (map_addr_to_serpar_number(&msg[0]) == 0) { + if (num == 1) /* write */ + return dib8096p_tuner_write_serpar(i2c_adap, msg, 1); + else /* read */ + return dib8096p_tuner_read_serpar(i2c_adap, msg, 2); + } + return num; +} + +static int dib8096p_rw_on_apb(struct i2c_adapter *i2c_adap, + struct i2c_msg msg[], int num, u16 apb_address) +{ + struct dib8000_state *state = i2c_get_adapdata(i2c_adap); + u16 word; + + if (num == 1) { /* write */ + dib8000_write_word(state, apb_address, + ((msg[0].buf[1] << 8) | (msg[0].buf[2]))); + } else { + word = dib8000_read_word(state, apb_address); + msg[1].buf[0] = (word >> 8) & 0xff; + msg[1].buf[1] = (word) & 0xff; + } + return num; +} + +static int dib8096p_tuner_xfer(struct i2c_adapter *i2c_adap, + struct i2c_msg msg[], int num) +{ + struct dib8000_state *state = i2c_get_adapdata(i2c_adap); + u16 apb_address = 0, word; + int i = 0; + + switch (msg[0].buf[0]) { + case 0x12: + apb_address = 1920; + break; + case 0x14: + apb_address = 1921; + break; + case 0x24: + apb_address = 1922; + break; + case 0x1a: + apb_address = 1923; + break; + case 0x22: + apb_address = 1924; + break; + case 0x33: + apb_address = 1926; + break; + case 0x34: + apb_address = 1927; + break; + case 0x35: + apb_address = 1928; + break; + case 0x36: + apb_address = 1929; + break; + case 0x37: + apb_address = 1930; + break; + case 0x38: + apb_address = 1931; + break; + case 0x39: + apb_address = 1932; + break; + case 0x2a: + apb_address = 1935; + break; + case 0x2b: + apb_address = 1936; + break; + case 0x2c: + apb_address = 1937; + break; + case 0x2d: + apb_address = 1938; + break; + case 0x2e: + apb_address = 1939; + break; + case 0x2f: + apb_address = 1940; + break; + case 0x30: + apb_address = 1941; + break; + case 0x31: + apb_address = 1942; + break; + case 0x32: + apb_address = 1943; + break; + case 0x3e: + apb_address = 1944; + break; + case 0x3f: + apb_address = 1945; + break; + case 0x40: + apb_address = 1948; + break; + case 0x25: + apb_address = 936; + break; + case 0x26: + apb_address = 937; + break; + case 0x27: + apb_address = 938; + break; + case 0x28: + apb_address = 939; + break; + case 0x1d: + /* get sad sel request */ + i = ((dib8000_read_word(state, 921) >> 12)&0x3); + word = dib8000_read_word(state, 924+i); + msg[1].buf[0] = (word >> 8) & 0xff; + msg[1].buf[1] = (word) & 0xff; + return num; + case 0x1f: + if (num == 1) { /* write */ + word = (u16) ((msg[0].buf[1] << 8) | + msg[0].buf[2]); + /* in the VGAMODE Sel are located on bit 0/1 */ + word &= 0x3; + word = (dib8000_read_word(state, 921) & + ~(3<<12)) | (word<<12); + /* Set the proper input */ + dib8000_write_word(state, 921, word); + return num; + } + } + + if (apb_address != 0) /* R/W acces via APB */ + return dib8096p_rw_on_apb(i2c_adap, msg, num, apb_address); + else /* R/W access via SERPAR */ + return dib8096p_tuner_rw_serpar(i2c_adap, msg, num); + + return 0; +} + +static u32 dib8096p_i2c_func(struct i2c_adapter *adapter) +{ + return I2C_FUNC_I2C; +} + +static struct i2c_algorithm dib8096p_tuner_xfer_algo = { + .master_xfer = dib8096p_tuner_xfer, + .functionality = dib8096p_i2c_func, +}; + +struct i2c_adapter *dib8096p_get_i2c_tuner(struct dvb_frontend *fe) +{ + struct dib8000_state *st = fe->demodulator_priv; + return &st->dib8096p_tuner_adap; +} +EXPORT_SYMBOL(dib8096p_get_i2c_tuner); + +int dib8096p_tuner_sleep(struct dvb_frontend *fe, int onoff) +{ + struct dib8000_state *state = fe->demodulator_priv; + u16 en_cur_state; + + dprintk("sleep dib8096p: %d", onoff); + + en_cur_state = dib8000_read_word(state, 1922); + + /* LNAs and MIX are ON and therefore it is a valid configuration */ + if (en_cur_state > 0xff) + state->tuner_enable = en_cur_state ; + + if (onoff) + en_cur_state &= 0x00ff; + else { + if (state->tuner_enable != 0) + en_cur_state = state->tuner_enable; + } + + dib8000_write_word(state, 1922, en_cur_state); + + return 0; +} +EXPORT_SYMBOL(dib8096p_tuner_sleep); + static const s32 lut_1000ln_mant[] = { 908, 7003, 7090, 7170, 7244, 7313, 7377, 7438, 7495, 7549, 7600 @@ -1051,6 +1815,26 @@ s32 dib8000_get_adc_power(struct dvb_frontend *fe, u8 mode) } EXPORT_SYMBOL(dib8000_get_adc_power); +int dib8090p_get_dc_power(struct dvb_frontend *fe, u8 IQ) +{ + struct dib8000_state *state = fe->demodulator_priv; + int val = 0; + + switch (IQ) { + case 1: + val = dib8000_read_word(state, 403); + break; + case 0: + val = dib8000_read_word(state, 404); + break; + } + if (val & 0x200) + val -= 1024; + + return val; +} +EXPORT_SYMBOL(dib8090p_get_dc_power); + static void dib8000_update_timf(struct dib8000_state *state) { u32 timf = state->timf = dib8000_read32(state, 435); @@ -1060,6 +1844,26 @@ static void dib8000_update_timf(struct dib8000_state *state) dprintk("Updated timing frequency: %d (default: %d)", state->timf, state->timf_default); } +u32 dib8000_ctrl_timf(struct dvb_frontend *fe, uint8_t op, uint32_t timf) +{ + struct dib8000_state *state = fe->demodulator_priv; + + switch (op) { + case DEMOD_TIMF_SET: + state->timf = timf; + break; + case DEMOD_TIMF_UPDATE: + dib8000_update_timf(state); + break; + case DEMOD_TIMF_GET: + break; + } + dib8000_set_bandwidth(state->fe[0], 6000); + + return state->timf; +} +EXPORT_SYMBOL(dib8000_ctrl_timf); + static const u16 adc_target_16dB[11] = { (1 << 13) - 825 - 117, (1 << 13) - 837 - 117, @@ -1086,6 +1890,9 @@ static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosear u16 init_prbs = 0xfff; u16 ana_gain = 0; + if (state->revision == 0x8090) + dib8000_init_sdram(state); + if (state->ber_monitored_layer != LAYER_ALL) dib8000_write_word(state, 285, (dib8000_read_word(state, 285) & 0x60) | state->ber_monitored_layer); else @@ -1418,7 +2225,10 @@ static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosear dprintk("nbseg_diff = %X (%d)", seg_diff_mask, seg_diff_mask); state->differential_constellation = (seg_diff_mask != 0); - dib8000_set_diversity_in(state->fe[0], state->diversity_onoff); + if (state->revision != 0x8090) + dib8000_set_diversity_in(state->fe[0], state->diversity_onoff); + else + dib8096p_set_diversity_in(state->fe[0], state->diversity_onoff); if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) { if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 1) @@ -1870,7 +2680,7 @@ static int dib8000_tune(struct dvb_frontend *fe) { struct dib8000_state *state = fe->demodulator_priv; int ret = 0; - u16 value, mode = fft_to_mode(state); + u16 lock, value, mode = fft_to_mode(state); // we are already tuned - just resuming from suspend if (state == NULL) @@ -1924,7 +2734,11 @@ static int dib8000_tune(struct dvb_frontend *fe) } // we achieved a coff_cpil_lock - it's time to update the timf - if ((dib8000_read_word(state, 568) >> 11) & 0x1) + if (state->revision != 0x8090) + lock = dib8000_read_word(state, 568); + else + lock = dib8000_read_word(state, 570); + if ((lock >> 11) & 0x1) dib8000_update_timf(state); //now that tune is finished, lock0 should lock on fec_mpeg to output this lock on MP_LOCK. It's changed in autosearch start @@ -1946,11 +2760,14 @@ static int dib8000_wakeup(struct dvb_frontend *fe) u8 index_frontend; int ret; - dib8000_set_power_mode(state, DIB8000M_POWER_ALL); + dib8000_set_power_mode(state, DIB8000_POWER_ALL); dib8000_set_adc_state(state, DIBX000_ADC_ON); if (dib8000_set_adc_state(state, DIBX000_SLOW_ADC_ON) != 0) dprintk("could not start Slow ADC"); + if (state->revision != 0x8090) + dib8000_sad_calib(state); + for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) { ret = state->fe[index_frontend]->ops.init(state->fe[index_frontend]); if (ret < 0) @@ -1972,8 +2789,9 @@ static int dib8000_sleep(struct dvb_frontend *fe) return ret; } - dib8000_set_output_mode(fe, OUTMODE_HIGH_Z); - dib8000_set_power_mode(state, DIB8000M_POWER_INTERFACE_ONLY); + if (state->revision != 0x8090) + dib8000_set_output_mode(fe, OUTMODE_HIGH_Z); + dib8000_set_power_mode(state, DIB8000_POWER_INTERFACE_ONLY); return dib8000_set_adc_state(state, DIBX000_SLOW_ADC_OFF) | dib8000_set_adc_state(state, DIBX000_ADC_OFF); } @@ -2028,7 +2846,10 @@ static int dib8000_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_par fe->dtv_property_cache.isdbt_sb_mode = dib8000_read_word(state, 508) & 0x1; - val = dib8000_read_word(state, 570); + if (state->revision == 0x8090) + val = dib8000_read_word(state, 572); + else + val = dib8000_read_word(state, 570); fe->dtv_property_cache.inversion = (val & 0x40) >> 6; switch ((val & 0x30) >> 4) { case 1: @@ -2158,7 +2979,12 @@ static int dib8000_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_par state->fe[index_frontend]->dtv_property_cache.delivery_system = SYS_ISDBT; memcpy(&state->fe[index_frontend]->dtv_property_cache, &fe->dtv_property_cache, sizeof(struct dtv_frontend_properties)); - dib8000_set_output_mode(state->fe[index_frontend], OUTMODE_HIGH_Z); + if (state->revision != 0x8090) + dib8000_set_output_mode(state->fe[index_frontend], + OUTMODE_HIGH_Z); + else + dib8096p_set_output_mode(state->fe[index_frontend], + OUTMODE_HIGH_Z); if (state->fe[index_frontend]->ops.tuner_ops.set_params) state->fe[index_frontend]->ops.tuner_ops.set_params(state->fe[index_frontend], fep); @@ -2269,14 +3095,37 @@ static int dib8000_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_par ret = dib8000_tune(state->fe[index_frontend]); /* set output mode and diversity input */ - dib8000_set_output_mode(state->fe[0], state->cfg.output_mode); - for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) { - dib8000_set_output_mode(state->fe[index_frontend], OUTMODE_DIVERSITY); - dib8000_set_diversity_in(state->fe[index_frontend-1], 1); - } + if (state->revision != 0x8090) { + dib8000_set_output_mode(state->fe[0], state->cfg.output_mode); + for (index_frontend = 1; + (index_frontend < MAX_NUMBER_OF_FRONTENDS) && + (state->fe[index_frontend] != NULL); + index_frontend++) { + dib8000_set_output_mode(state->fe[index_frontend], + OUTMODE_DIVERSITY); + dib8000_set_diversity_in(state->fe[index_frontend-1], 1); + } - /* turn off the diversity of the last chip */ - dib8000_set_diversity_in(state->fe[index_frontend-1], 0); + /* turn off the diversity of the last chip */ + dib8000_set_diversity_in(state->fe[index_frontend-1], 0); + } else { + dib8096p_set_output_mode(state->fe[0], state->cfg.output_mode); + if (state->cfg.enMpegOutput == 0) { + dib8096p_setDibTxMux(state, MPEG_ON_DIBTX); + dib8096p_setHostBusMux(state, DIBTX_ON_HOSTBUS); + } + for (index_frontend = 1; + (index_frontend < MAX_NUMBER_OF_FRONTENDS) && + (state->fe[index_frontend] != NULL); + index_frontend++) { + dib8096p_set_output_mode(state->fe[index_frontend], + OUTMODE_DIVERSITY); + dib8096p_set_diversity_in(state->fe[index_frontend-1], 1); + } + + /* turn off the diversity of the last chip */ + dib8096p_set_diversity_in(state->fe[index_frontend-1], 0); + } return ret; } @@ -2285,15 +3134,22 @@ static u16 dib8000_read_lock(struct dvb_frontend *fe) { struct dib8000_state *state = fe->demodulator_priv; + if (state->revision == 0x8090) + return dib8000_read_word(state, 570); return dib8000_read_word(state, 568); } static int dib8000_read_status(struct dvb_frontend *fe, fe_status_t * stat) { struct dib8000_state *state = fe->demodulator_priv; - u16 lock_slave = 0, lock = dib8000_read_word(state, 568); + u16 lock_slave = 0, lock; u8 index_frontend; + if (state->revision == 0x8090) + lock = dib8000_read_word(state, 570); + else + lock = dib8000_read_word(state, 568); + for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) lock_slave |= dib8000_read_lock(state->fe[index_frontend]); @@ -2331,14 +3187,26 @@ static int dib8000_read_status(struct dvb_frontend *fe, fe_status_t * stat) static int dib8000_read_ber(struct dvb_frontend *fe, u32 * ber) { struct dib8000_state *state = fe->demodulator_priv; - *ber = (dib8000_read_word(state, 560) << 16) | dib8000_read_word(state, 561); // 13 segments + + /* 13 segments */ + if (state->revision == 0x8090) + *ber = (dib8000_read_word(state, 562) << 16) | + dib8000_read_word(state, 563); + else + *ber = (dib8000_read_word(state, 560) << 16) | + dib8000_read_word(state, 561); return 0; } static int dib8000_read_unc_blocks(struct dvb_frontend *fe, u32 * unc) { struct dib8000_state *state = fe->demodulator_priv; - *unc = dib8000_read_word(state, 565); // packet error on 13 seg + + /* packet error on 13 seg */ + if (state->revision == 0x8090) + *unc = dib8000_read_word(state, 567); + else + *unc = dib8000_read_word(state, 565); return 0; } @@ -2371,14 +3239,20 @@ static u32 dib8000_get_snr(struct dvb_frontend *fe) u32 n, s, exp; u16 val; - val = dib8000_read_word(state, 542); + if (state->revision != 0x8090) + val = dib8000_read_word(state, 542); + else + val = dib8000_read_word(state, 544); n = (val >> 6) & 0xff; exp = (val & 0x3f); if ((exp & 0x20) != 0) exp -= 0x40; n <<= exp+16; - val = dib8000_read_word(state, 543); + if (state->revision != 0x8090) + val = dib8000_read_word(state, 543); + else + val = dib8000_read_word(state, 545); s = (val >> 6) & 0xff; exp = (val & 0x3f); if ((exp & 0x20) != 0) @@ -2459,7 +3333,8 @@ struct dvb_frontend *dib8000_get_slave_frontend(struct dvb_frontend *fe, int sla EXPORT_SYMBOL(dib8000_get_slave_frontend); -int dib8000_i2c_enumeration(struct i2c_adapter *host, int no_of_demods, u8 default_addr, u8 first_addr) +int dib8000_i2c_enumeration(struct i2c_adapter *host, int no_of_demods, + u8 default_addr, u8 first_addr, u8 is_dib8096p) { int k = 0, ret = 0; u8 new_addr = 0; @@ -2489,9 +3364,12 @@ int dib8000_i2c_enumeration(struct i2c_adapter *host, int no_of_demods, u8 defau new_addr = first_addr + (k << 1); client.addr = new_addr; - dib8000_i2c_write16(&client, 1287, 0x0003); /* sram lead in, rdy */ - if (dib8000_identify(&client) == 0) { + if (!is_dib8096p) dib8000_i2c_write16(&client, 1287, 0x0003); /* sram lead in, rdy */ + if (dib8000_identify(&client) == 0) { + /* sram lead in, rdy */ + if (!is_dib8096p) + dib8000_i2c_write16(&client, 1287, 0x0003); client.addr = default_addr; if (dib8000_identify(&client) == 0) { dprintk("#%d: not identified", k); @@ -2550,6 +3428,7 @@ static void dib8000_release(struct dvb_frontend *fe) dvb_frontend_detach(st->fe[index_frontend]); dibx000_exit_i2c_master(&st->i2c_master); + i2c_del_adapter(&st->dib8096p_tuner_adap); kfree(st->fe[0]); kfree(st); } @@ -2652,6 +3531,15 @@ struct dvb_frontend *dib8000_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, s dibx000_init_i2c_master(&state->i2c_master, DIB8000, state->i2c.adap, state->i2c.addr); + /* init 8096p tuner adapter */ + strncpy(state->dib8096p_tuner_adap.name, "DiB8096P tuner interface", + sizeof(state->dib8096p_tuner_adap.name)); + state->dib8096p_tuner_adap.algo = &dib8096p_tuner_xfer_algo; + state->dib8096p_tuner_adap.algo_data = NULL; + state->dib8096p_tuner_adap.dev.parent = state->i2c.adap->dev.parent; + i2c_set_adapdata(&state->dib8096p_tuner_adap, state); + i2c_add_adapter(&state->dib8096p_tuner_adap); + dib8000_reset(fe); dib8000_write_word(state, 285, (dib8000_read_word(state, 285) & ~0x60) | (3 << 5)); /* ber_rs_len = 3 */ diff --git a/drivers/media/dvb/frontends/dib8000.h b/drivers/media/dvb/frontends/dib8000.h index 617f9eb..39591bb 100644 --- a/drivers/media/dvb/frontends/dib8000.h +++ b/drivers/media/dvb/frontends/dib8000.h @@ -32,6 +32,7 @@ struct dib8000_config { u8 div_cfg; u8 output_mode; u8 refclksel; + u8 enMpegOutput:1; }; #define DEFAULT_DIB8000_I2C_ADDRESS 18 @@ -40,7 +41,8 @@ struct dib8000_config { extern struct dvb_frontend *dib8000_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib8000_config *cfg); extern struct i2c_adapter *dib8000_get_i2c_master(struct dvb_frontend *, enum dibx000_i2c_interface, int); -extern int dib8000_i2c_enumeration(struct i2c_adapter *host, int no_of_demods, u8 default_addr, u8 first_addr); +extern int dib8000_i2c_enumeration(struct i2c_adapter *host, int no_of_demods, + u8 default_addr, u8 first_addr, u8 is_dib8096p); extern int dib8000_set_gpio(struct dvb_frontend *, u8 num, u8 dir, u8 val); extern int dib8000_set_wbd_ref(struct dvb_frontend *, u16 value); @@ -50,6 +52,13 @@ extern int dib8000_set_tune_state(struct dvb_frontend *fe, enum frontend_tune_st extern enum frontend_tune_state dib8000_get_tune_state(struct dvb_frontend *fe); extern void dib8000_pwm_agc_reset(struct dvb_frontend *fe); extern s32 dib8000_get_adc_power(struct dvb_frontend *fe, u8 mode); +extern struct i2c_adapter *dib8096p_get_i2c_tuner(struct dvb_frontend *fe); +extern int dib8096p_tuner_sleep(struct dvb_frontend *fe, int onoff); +extern int dib8090p_get_dc_power(struct dvb_frontend *fe, u8 IQ); +extern u32 dib8000_ctrl_timf(struct dvb_frontend *fe, + uint8_t op, uint32_t timf); +extern int dib8000_update_pll(struct dvb_frontend *fe, + struct dibx000_bandwidth_config *pll); extern int dib8000_set_slave_frontend(struct dvb_frontend *fe, struct dvb_frontend *fe_slave); extern int dib8000_remove_slave_frontend(struct dvb_frontend *fe); extern struct dvb_frontend *dib8000_get_slave_frontend(struct dvb_frontend *fe, int slave_index); @@ -66,7 +75,9 @@ static inline struct i2c_adapter *dib8000_get_i2c_master(struct dvb_frontend *fe return NULL; } -static inline int dib8000_i2c_enumeration(struct i2c_adapter *host, int no_of_demods, u8 default_addr, u8 first_addr) +static inline int dib8000_i2c_enumeration(struct i2c_adapter *host, + int no_of_demods, u8 default_addr, u8 first_addr, + u8 is_dib8096p) { printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); return -ENODEV; @@ -109,11 +120,38 @@ static inline void dib8000_pwm_agc_reset(struct dvb_frontend *fe) { printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); } +static inline struct i2c_adapter *dib8096p_get_i2c_tuner(struct dvb_frontend *fe) +{ + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); + return NULL; +} +static inline int dib8096p_tuner_sleep(struct dvb_frontend *fe, int onoff) +{ + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); + return 0; +} static inline s32 dib8000_get_adc_power(struct dvb_frontend *fe, u8 mode) { printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); return 0; } +static inline int dib8090p_get_dc_power(struct dvb_frontend *fe, u8 IQ) +{ + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); + return 0; +} +static inline u32 dib8000_ctrl_timf(struct dvb_frontend *fe, + uint8_t op, uint32_t timf) +{ + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); + return 0; +} +static inline int dib8000_update_pll(struct dvb_frontend *fe, + struct dibx000_bandwidth_config *pll) +{ + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); + return -ENODEV; +} static inline int dib8000_set_slave_frontend(struct dvb_frontend *fe, struct dvb_frontend *fe_slave) { printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); diff --git a/drivers/media/dvb/frontends/dibx000_common.h b/drivers/media/dvb/frontends/dibx000_common.h index 5e01147..02e6431 100644 --- a/drivers/media/dvb/frontends/dibx000_common.h +++ b/drivers/media/dvb/frontends/dibx000_common.h @@ -276,4 +276,11 @@ struct dibSubbandSelection { #define DEMOD_TIMF_GET 0x01 #define DEMOD_TIMF_UPDATE 0x02 +#define MPEG_ON_DIBTX 1 +#define DIV_ON_DIBTX 2 +#define ADC_ON_DIBTX 3 +#define DEMOUT_ON_HOSTBUS 4 +#define DIBTX_ON_HOSTBUS 5 +#define MPEG_ON_HOSTBUS 6 + #endif -- cgit v0.10.2 From 88f3a3584c74af84cd0476ee94af6234b50ce697 Mon Sep 17 00:00:00 2001 From: Olivier Grenie Date: Wed, 10 Aug 2011 05:28:38 -0300 Subject: [media] dib8096P: add the reference board TFE8096P The intend of this patch is to add the support for the DiBcom reference board TFE8096P. Signed-off-by: Olivier Grenie Signed-off-by: Patrick Boettcher Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/dvb/dvb-usb/dib0700_devices.c b/drivers/media/dvb/dvb-usb/dib0700_devices.c index b7b4b65..823c356 100644 --- a/drivers/media/dvb/dvb-usb/dib0700_devices.c +++ b/drivers/media/dvb/dvb-usb/dib0700_devices.c @@ -1641,6 +1641,261 @@ static int nim8096md_frontend_attach(struct dvb_usb_adapter *adap) return fe_slave == NULL ? -ENODEV : 0; } +/* TFE8096P */ +static struct dibx000_agc_config dib8096p_agc_config[2] = { + { + .band_caps = BAND_UHF, + /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, + P_agc_freq_pwm_div=1, P_agc_inv_pwm1=0, + P_agc_inv_pwm2=0, P_agc_inh_dc_rv_est=0, + P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5, + P_agc_write=0 */ + .setup = (0 << 15) | (0 << 14) | (5 << 11) + | (0 << 10) | (0 << 9) | (0 << 8) | (3 << 5) + | (0 << 4) | (5 << 1) | (0 << 0), + + .inv_gain = 684, + .time_stabiliz = 10, + + .alpha_level = 0, + .thlock = 118, + + .wbd_inv = 0, + .wbd_ref = 1200, + .wbd_sel = 3, + .wbd_alpha = 5, + + .agc1_max = 65535, + .agc1_min = 0, + + .agc2_max = 32767, + .agc2_min = 0, + + .agc1_pt1 = 0, + .agc1_pt2 = 0, + .agc1_pt3 = 105, + .agc1_slope1 = 0, + .agc1_slope2 = 156, + .agc2_pt1 = 105, + .agc2_pt2 = 255, + .agc2_slope1 = 54, + .agc2_slope2 = 0, + + .alpha_mant = 28, + .alpha_exp = 26, + .beta_mant = 31, + .beta_exp = 51, + + .perform_agc_softsplit = 0, + } , { + .band_caps = BAND_FM | BAND_VHF | BAND_CBAND, + /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, + P_agc_freq_pwm_div=1, P_agc_inv_pwm1=0, + P_agc_inv_pwm2=0, P_agc_inh_dc_rv_est=0, + P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5, + P_agc_write=0 */ + .setup = (0 << 15) | (0 << 14) | (5 << 11) + | (0 << 10) | (0 << 9) | (0 << 8) | (3 << 5) + | (0 << 4) | (5 << 1) | (0 << 0), + + .inv_gain = 732, + .time_stabiliz = 10, + + .alpha_level = 0, + .thlock = 118, + + .wbd_inv = 0, + .wbd_ref = 1200, + .wbd_sel = 3, + .wbd_alpha = 5, + + .agc1_max = 65535, + .agc1_min = 0, + + .agc2_max = 32767, + .agc2_min = 0, + + .agc1_pt1 = 0, + .agc1_pt2 = 0, + .agc1_pt3 = 98, + .agc1_slope1 = 0, + .agc1_slope2 = 167, + .agc2_pt1 = 98, + .agc2_pt2 = 255, + .agc2_slope1 = 52, + .agc2_slope2 = 0, + + .alpha_mant = 28, + .alpha_exp = 26, + .beta_mant = 31, + .beta_exp = 51, + + .perform_agc_softsplit = 0, + } +}; + +static struct dibx000_bandwidth_config dib8096p_clock_config_12_mhz = { + 108000, 13500, + 1, 9, 1, 0, 0, + 0, 0, 0, 0, 2, + (3 << 14) | (1 << 12) | (524 << 0), + (0 << 25) | 0, + 20199729, + 12000000, +}; + +static struct dib8000_config tfe8096p_dib8000_config = { + .output_mpeg2_in_188_bytes = 1, + .hostbus_diversity = 1, + .update_lna = NULL, + + .agc_config_count = 2, + .agc = dib8096p_agc_config, + .pll = &dib8096p_clock_config_12_mhz, + + .gpio_dir = DIB8000_GPIO_DEFAULT_DIRECTIONS, + .gpio_val = DIB8000_GPIO_DEFAULT_VALUES, + .gpio_pwm_pos = DIB8000_GPIO_DEFAULT_PWM_POS, + + .agc_control = NULL, + .diversity_delay = 48, + .output_mode = OUTMODE_MPEG2_FIFO, + .enMpegOutput = 1, +}; + +static struct dib0090_wbd_slope dib8096p_wbd_table[] = { + { 380, 81, 850, 64, 540, 4}, + { 860, 51, 866, 21, 375, 4}, + {1700, 0, 250, 0, 100, 6}, + {2600, 0, 250, 0, 100, 6}, + { 0xFFFF, 0, 0, 0, 0, 0}, +}; + +static const struct dib0090_config tfe8096p_dib0090_config = { + .io.clock_khz = 12000, + .io.pll_bypass = 0, + .io.pll_range = 0, + .io.pll_prediv = 3, + .io.pll_loopdiv = 6, + .io.adc_clock_ratio = 0, + .io.pll_int_loop_filt = 0, + .reset = dib8096p_tuner_sleep, + .sleep = dib8096p_tuner_sleep, + + .freq_offset_khz_uhf = -143, + .freq_offset_khz_vhf = -143, + + .get_adc_power = dib8090_get_adc_power, + + .clkouttobamse = 1, + .analog_output = 0, + + .wbd_vhf_offset = 0, + .wbd_cband_offset = 0, + .use_pwm_agc = 1, + .clkoutdrive = 0, + + .fref_clock_ratio = 1, + + .wbd = dib8096p_wbd_table, + + .ls_cfg_pad_drv = 0, + .data_tx_drv = 0, + .low_if = NULL, + .in_soc = 1, + .force_cband_input = 0, +}; + +struct dibx090p_adc { + u32 freq; /* RF freq MHz */ + u32 timf; /* New Timf */ + u32 pll_loopdiv; /* New prediv */ + u32 pll_prediv; /* New loopdiv */ +}; + +struct dibx090p_adc dib8090p_adc_tab[] = { + { 50000, 17043521, 16, 3}, /* 64 MHz */ + {878000, 20199729, 9, 1}, /* 60 MHz */ + {0xffffffff, 0, 0, 0}, /* 60 MHz */ +}; + +static int dib8096p_agc_startup(struct dvb_frontend *fe, + struct dvb_frontend_parameters *fep) +{ + struct dvb_usb_adapter *adap = fe->dvb->priv; + struct dib0700_adapter_state *state = adap->priv; + struct dibx000_bandwidth_config pll; + u16 target; + int better_sampling_freq = 0, ret; + struct dibx090p_adc *adc_table = &dib8090p_adc_tab[0]; + + ret = state->set_param_save(fe, fep); + if (ret < 0) + return ret; + memset(&pll, 0, sizeof(struct dibx000_bandwidth_config)); + + dib0090_pwm_gain_reset(fe); + /* dib0090_get_wbd_target is returning any possible + temperature compensated wbd-target */ + target = (dib0090_get_wbd_target(fe) * 8 + 1) / 2; + dib8000_set_wbd_ref(fe, target); + + + while (fep->frequency / 1000 > adc_table->freq) { + better_sampling_freq = 1; + adc_table++; + } + + if ((adc_table->freq != 0xffffffff) && better_sampling_freq) { + pll.pll_ratio = adc_table->pll_loopdiv; + pll.pll_prediv = adc_table->pll_prediv; + dib8000_update_pll(fe, &pll); + dib8000_ctrl_timf(fe, DEMOD_TIMF_SET, adc_table->timf); + } + return 0; +} + +static int tfe8096p_frontend_attach(struct dvb_usb_adapter *adap) +{ + dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1); + msleep(20); + dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1); + dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1); + dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1); + + dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0); + + dib0700_ctrl_clock(adap->dev, 72, 1); + + msleep(20); + dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1); + msleep(20); + dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1); + + dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x10, 0x80, 1); + + adap->fe_adap[0].fe = dvb_attach(dib8000_attach, + &adap->dev->i2c_adap, 0x80, &tfe8096p_dib8000_config); + + return adap->fe_adap[0].fe == NULL ? -ENODEV : 0; +} + +static int tfe8096p_tuner_attach(struct dvb_usb_adapter *adap) +{ + struct dib0700_adapter_state *st = adap->priv; + struct i2c_adapter *tun_i2c = dib8096p_get_i2c_tuner(adap->fe_adap[0].fe); + + if (dvb_attach(dib0090_register, adap->fe_adap[0].fe, tun_i2c, + &tfe8096p_dib0090_config) == NULL) + return -ENODEV; + + dib8000_set_gpio(adap->fe_adap[0].fe, 8, 0, 1); + + st->set_param_save = adap->fe_adap[0].fe->ops.tuner_ops.set_params; + adap->fe_adap[0].fe->ops.tuner_ops.set_params = dib8096p_agc_startup; + return 0; +} + /* STK9090M */ static int dib90x0_pid_filter(struct dvb_usb_adapter *adapter, int index, u16 pid, int onoff) { @@ -3234,6 +3489,7 @@ struct usb_device_id dib0700_usb_id_table[] = { { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV340E_SE) }, { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_TFE7090E) }, { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_TFE7790E) }, +/* 80 */{ USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_TFE8096P) }, { 0 } /* Terminating entry */ }; MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table); @@ -4379,6 +4635,47 @@ struct dvb_usb_device_properties dib0700_devices[] = { RC_TYPE_NEC, .change_protocol = dib0700_change_protocol, }, + }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, + .num_adapters = 1, + .adapter = { + { + .num_frontends = 1, + .fe = {{ + .caps = DVB_USB_ADAP_HAS_PID_FILTER | + DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, + .pid_filter_count = 32, + .pid_filter = stk80xx_pid_filter, + .pid_filter_ctrl = stk80xx_pid_filter_ctrl, + .frontend_attach = tfe8096p_frontend_attach, + .tuner_attach = tfe8096p_tuner_attach, + + DIB0700_DEFAULT_STREAMING_CONFIG(0x02), + + } }, + + .size_of_priv = + sizeof(struct dib0700_adapter_state), + }, + }, + + .num_device_descs = 1, + .devices = { + { "DiBcom TFE8096P reference design", + { &dib0700_usb_id_table[80], NULL }, + { NULL }, + }, + }, + + .rc.core = { + .rc_interval = DEFAULT_RC_INTERVAL, + .rc_codes = RC_MAP_DIB0700_RC5_TABLE, + .module_name = "dib0700", + .rc_query = dib0700_rc_query_old_firmware, + .allowed_protos = RC_TYPE_RC5 | + RC_TYPE_RC6 | + RC_TYPE_NEC, + .change_protocol = dib0700_change_protocol, + }, }, }; diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h index 3f437eb..18be4b1 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h +++ b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h @@ -109,6 +109,7 @@ #define USB_PID_DIBCOM_STK807XPVR 0x1f98 #define USB_PID_DIBCOM_STK8096GP 0x1fa0 #define USB_PID_DIBCOM_NIM8096MD 0x1fa8 +#define USB_PID_DIBCOM_TFE8096P 0x1f9C #define USB_PID_DIBCOM_ANCHOR_2135_COLD 0x2131 #define USB_PID_DIBCOM_STK7770P 0x1e80 #define USB_PID_DIBCOM_NIM7090 0x1bb2 -- cgit v0.10.2 From d1190024f0277a225c5926dbeb23306eb55035be Mon Sep 17 00:00:00 2001 From: Olivier Grenie Date: Mon, 29 Aug 2011 10:58:47 -0300 Subject: [media] dib9090: limit the I2C speed The intend of this patch is to limit the maximum I2C speed. Signed-off-by: Olivier Grenie Signed-off-by: Patrick Boettcher Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/dvb/dvb-usb/dib0700_devices.c b/drivers/media/dvb/dvb-usb/dib0700_devices.c index 823c356..d0174fd 100644 --- a/drivers/media/dvb/dvb-usb/dib0700_devices.c +++ b/drivers/media/dvb/dvb-usb/dib0700_devices.c @@ -2138,7 +2138,7 @@ static int dib9090_tuner_attach(struct dvb_usb_adapter *adap) i2c = dib9000_get_i2c_master(adap->fe_adap[0].fe, DIBX000_I2C_INTERFACE_GPIO_1_2, 0); if (dib01x0_pmu_update(i2c, data_dib190, 10) != 0) return -ENODEV; - dib0700_set_i2c_speed(adap->dev, 2000); + dib0700_set_i2c_speed(adap->dev, 1500); if (dib9000_firmware_post_pll_init(adap->fe_adap[0].fe) < 0) return -ENODEV; release_firmware(state->frontend_firmware); @@ -2217,7 +2217,8 @@ static int nim9090md_tuner_attach(struct dvb_usb_adapter *adap) i2c = dib9000_get_i2c_master(adap->fe_adap[0].fe, DIBX000_I2C_INTERFACE_GPIO_1_2, 0); if (dib01x0_pmu_update(i2c, data_dib190, 10) < 0) return -ENODEV; - dib0700_set_i2c_speed(adap->dev, 2000); + + dib0700_set_i2c_speed(adap->dev, 1500); if (dib9000_firmware_post_pll_init(adap->fe_adap[0].fe) < 0) return -ENODEV; @@ -2230,7 +2231,7 @@ static int nim9090md_tuner_attach(struct dvb_usb_adapter *adap) if (dvb_attach(dib0090_fw_register, fe_slave, i2c, &nim9090md_dib0090_config[1]) == NULL) return -ENODEV; fe_slave->dvb = adap->fe_adap[0].fe->dvb; - dib9000_fw_set_component_bus_speed(adap->fe_adap[0].fe, 2000); + dib9000_fw_set_component_bus_speed(adap->fe_adap[0].fe, 1500); if (dib9000_firmware_post_pll_init(fe_slave) < 0) return -ENODEV; } -- cgit v0.10.2 From 53090aada474fe10052602ca3f46701591b666a5 Mon Sep 17 00:00:00 2001 From: Thomas Meyer Date: Thu, 17 Nov 2011 18:43:40 -0300 Subject: [media] drxd: Use kmemdup rather than duplicating its implementation The semantic patch that makes this change is available in scripts/coccinelle/api/memdup.cocci. Signed-off-by: Thomas Meyer Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/dvb/frontends/drxd_hard.c b/drivers/media/dvb/frontends/drxd_hard.c index 88e46f4..beb6775 100644 --- a/drivers/media/dvb/frontends/drxd_hard.c +++ b/drivers/media/dvb/frontends/drxd_hard.c @@ -914,14 +914,13 @@ static int load_firmware(struct drxd_state *state, const char *fw_name) return -EIO; } - state->microcode = kmalloc(fw->size, GFP_KERNEL); + state->microcode = kmemdup(fw->data, fw->size, GFP_KERNEL); if (state->microcode == NULL) { release_firmware(fw); printk(KERN_ERR "drxd: firmware load failure: no memory\n"); return -ENOMEM; } - memcpy(state->microcode, fw->data, fw->size); state->microcode_length = fw->size; release_firmware(fw); return 0; -- cgit v0.10.2 From 68dd9dd4113a7d2bd329590091a3f97fee3fd659 Mon Sep 17 00:00:00 2001 From: Thomas Meyer Date: Thu, 17 Nov 2011 18:43:40 -0300 Subject: [media] dw2102: Use kmemdup rather than duplicating its implementation The semantic patch that makes this change is available in scripts/coccinelle/api/memdup.cocci. Signed-off-by: Thomas Meyer Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/dvb/dvb-usb/dw2102.c b/drivers/media/dvb/dvb-usb/dw2102.c index f103ec1..41cff37 100644 --- a/drivers/media/dvb/dvb-usb/dw2102.c +++ b/drivers/media/dvb/dvb-usb/dw2102.c @@ -1859,12 +1859,11 @@ static struct dvb_usb_device_properties su3000_properties = { static int dw2102_probe(struct usb_interface *intf, const struct usb_device_id *id) { - p1100 = kzalloc(sizeof(struct dvb_usb_device_properties), GFP_KERNEL); + p1100 = kmemdup(&s6x0_properties, + sizeof(struct dvb_usb_device_properties), GFP_KERNEL); if (!p1100) return -ENOMEM; /* copy default structure */ - memcpy(p1100, &s6x0_properties, - sizeof(struct dvb_usb_device_properties)); /* fill only different fields */ p1100->firmware = "dvb-usb-p1100.fw"; p1100->devices[0] = d1100; @@ -1872,13 +1871,12 @@ static int dw2102_probe(struct usb_interface *intf, p1100->rc.legacy.rc_map_size = ARRAY_SIZE(rc_map_tbs_table); p1100->adapter->fe[0].frontend_attach = stv0288_frontend_attach; - s660 = kzalloc(sizeof(struct dvb_usb_device_properties), GFP_KERNEL); + s660 = kmemdup(&s6x0_properties, + sizeof(struct dvb_usb_device_properties), GFP_KERNEL); if (!s660) { kfree(p1100); return -ENOMEM; } - memcpy(s660, &s6x0_properties, - sizeof(struct dvb_usb_device_properties)); s660->firmware = "dvb-usb-s660.fw"; s660->num_device_descs = 3; s660->devices[0] = d660; @@ -1886,14 +1884,13 @@ static int dw2102_probe(struct usb_interface *intf, s660->devices[2] = d480_2; s660->adapter->fe[0].frontend_attach = ds3000_frontend_attach; - p7500 = kzalloc(sizeof(struct dvb_usb_device_properties), GFP_KERNEL); + p7500 = kmemdup(&s6x0_properties, + sizeof(struct dvb_usb_device_properties), GFP_KERNEL); if (!p7500) { kfree(p1100); kfree(s660); return -ENOMEM; } - memcpy(p7500, &s6x0_properties, - sizeof(struct dvb_usb_device_properties)); p7500->firmware = "dvb-usb-p7500.fw"; p7500->devices[0] = d7500; p7500->rc.legacy.rc_map_table = rc_map_tbs_table; -- cgit v0.10.2 From 82c80f8371835f861bdbe50eefa5f49888d23210 Mon Sep 17 00:00:00 2001 From: Thomas Meyer Date: Thu, 17 Nov 2011 18:43:40 -0300 Subject: [media] v4l: Casting (void *) value returned by kmalloc is useless The semantic patch that makes this change is available in scripts/coccinelle/api/alloc/drop_kmalloc_cast.cocci. Signed-off-by: Thomas Meyer Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/vino.c b/drivers/media/video/vino.c index 52a0a37..4d7391e 100644 --- a/drivers/media/video/vino.c +++ b/drivers/media/video/vino.c @@ -708,7 +708,7 @@ static int vino_allocate_buffer(struct vino_framebuffer *fb, size, count); /* allocate memory for table with virtual (page) addresses */ - fb->desc_table.virtual = (unsigned long *) + fb->desc_table.virtual = kmalloc(count * sizeof(unsigned long), GFP_KERNEL); if (!fb->desc_table.virtual) return -ENOMEM; -- cgit v0.10.2 From 0ceaec188e7784c7f9ab5fca110fecb790837dbc Mon Sep 17 00:00:00 2001 From: Thomas Meyer Date: Thu, 17 Nov 2011 19:12:18 -0300 Subject: [media] cx25821: Use kmemdup rather than duplicating its implementation The semantic patch that makes this change is available in scripts/coccinelle/api/memdup.cocci. Signed-off-by: Thomas Meyer Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/cx25821/cx25821-audio-upstream.c b/drivers/media/video/cx25821/cx25821-audio-upstream.c index 4dc2a24..20c7ca3 100644 --- a/drivers/media/video/cx25821/cx25821-audio-upstream.c +++ b/drivers/media/video/cx25821/cx25821-audio-upstream.c @@ -733,25 +733,22 @@ int cx25821_audio_upstream_init(struct cx25821_dev *dev, int channel_select) if (dev->input_audiofilename) { str_length = strlen(dev->input_audiofilename); - dev->_audiofilename = kmalloc(str_length + 1, GFP_KERNEL); + dev->_audiofilename = kmemdup(dev->input_audiofilename, + str_length + 1, GFP_KERNEL); if (!dev->_audiofilename) goto error; - memcpy(dev->_audiofilename, dev->input_audiofilename, - str_length + 1); - /* Default if filename is empty string */ if (strcmp(dev->input_audiofilename, "") == 0) dev->_audiofilename = "/root/audioGOOD.wav"; } else { str_length = strlen(_defaultAudioName); - dev->_audiofilename = kmalloc(str_length + 1, GFP_KERNEL); + dev->_audiofilename = kmemdup(_defaultAudioName, + str_length + 1, GFP_KERNEL); if (!dev->_audiofilename) goto error; - - memcpy(dev->_audiofilename, _defaultAudioName, str_length + 1); } retval = cx25821_sram_channel_setup_upstream_audio(dev, sram_ch, diff --git a/drivers/media/video/cx25821/cx25821-video-upstream-ch2.c b/drivers/media/video/cx25821/cx25821-video-upstream-ch2.c index 6401ce8..5a157cf 100644 --- a/drivers/media/video/cx25821/cx25821-video-upstream-ch2.c +++ b/drivers/media/video/cx25821/cx25821-video-upstream-ch2.c @@ -747,22 +747,18 @@ int cx25821_vidupstream_init_ch2(struct cx25821_dev *dev, int channel_select, if (dev->input_filename_ch2) { str_length = strlen(dev->input_filename_ch2); - dev->_filename_ch2 = kmalloc(str_length + 1, GFP_KERNEL); + dev->_filename_ch2 = kmemdup(dev->input_filename_ch2, + str_length + 1, GFP_KERNEL); if (!dev->_filename_ch2) goto error; - - memcpy(dev->_filename_ch2, dev->input_filename_ch2, - str_length + 1); } else { str_length = strlen(dev->_defaultname_ch2); - dev->_filename_ch2 = kmalloc(str_length + 1, GFP_KERNEL); + dev->_filename_ch2 = kmemdup(dev->_defaultname_ch2, + str_length + 1, GFP_KERNEL); if (!dev->_filename_ch2) goto error; - - memcpy(dev->_filename_ch2, dev->_defaultname_ch2, - str_length + 1); } /* Default if filename is empty string */ diff --git a/drivers/media/video/cx25821/cx25821-video-upstream.c b/drivers/media/video/cx25821/cx25821-video-upstream.c index 1032263..21e7d65 100644 --- a/drivers/media/video/cx25821/cx25821-video-upstream.c +++ b/drivers/media/video/cx25821/cx25821-video-upstream.c @@ -794,20 +794,18 @@ int cx25821_vidupstream_init_ch1(struct cx25821_dev *dev, int channel_select, if (dev->input_filename) { str_length = strlen(dev->input_filename); - dev->_filename = kmalloc(str_length + 1, GFP_KERNEL); + dev->_filename = kmemdup(dev->input_filename, str_length + 1, + GFP_KERNEL); if (!dev->_filename) goto error; - - memcpy(dev->_filename, dev->input_filename, str_length + 1); } else { str_length = strlen(dev->_defaultname); - dev->_filename = kmalloc(str_length + 1, GFP_KERNEL); + dev->_filename = kmemdup(dev->_defaultname, str_length + 1, + GFP_KERNEL); if (!dev->_filename) goto error; - - memcpy(dev->_filename, dev->_defaultname, str_length + 1); } /* Default if filename is empty string */ -- cgit v0.10.2 From 6d00c9aa2bb98909de21eaaf767b9ed76fe26f86 Mon Sep 17 00:00:00 2001 From: Thomas Meyer Date: Thu, 17 Nov 2011 18:43:40 -0300 Subject: [media] pwc: Use kmemdup rather than duplicating its implementation The semantic patch that makes this change is available in scripts/coccinelle/api/memdup.cocci. Signed-off-by: Thomas Meyer Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/pwc/pwc-ctrl.c b/drivers/media/video/pwc/pwc-ctrl.c index 3977add..b42c239 100644 --- a/drivers/media/video/pwc/pwc-ctrl.c +++ b/drivers/media/video/pwc/pwc-ctrl.c @@ -113,10 +113,9 @@ static int _send_control_msg(struct pwc_device *pdev, void *kbuf = NULL; if (buflen) { - kbuf = kmalloc(buflen, GFP_KERNEL); /* not allowed on stack */ + kbuf = kmemdup(buf, buflen, GFP_KERNEL); /* not allowed on stack */ if (kbuf == NULL) return -ENOMEM; - memcpy(kbuf, buf, buflen); } rc = usb_control_msg(pdev->udev, usb_sndctrlpipe(pdev->udev, 0), -- cgit v0.10.2 From 7e5219d18e93dd23e834a53b1ea73ead19cfeeb1 Mon Sep 17 00:00:00 2001 From: Pete Date: Fri, 18 Nov 2011 15:00:15 -0300 Subject: [media] go7007: Fix 2250 urb type commit a846d8fce9e8be30046be3c512982bd0345e7015 The 2250 board uses bulk endpoint for interrupt handling, and should use a bulk urb instead of an int urb. Signed-off-by: Pete Eberlein Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/staging/media/go7007/go7007-usb.c b/drivers/staging/media/go7007/go7007-usb.c index 3db3b0a..cffb0b3 100644 --- a/drivers/staging/media/go7007/go7007-usb.c +++ b/drivers/staging/media/go7007/go7007-usb.c @@ -1054,7 +1054,13 @@ static int go7007_usb_probe(struct usb_interface *intf, else go->hpi_ops = &go7007_usb_onboard_hpi_ops; go->hpi_context = usb; - usb_fill_int_urb(usb->intr_urb, usb->usbdev, + if (go->board_id == GO7007_BOARDID_SENSORAY_2250) + usb_fill_bulk_urb(usb->intr_urb, usb->usbdev, + usb_rcvbulkpipe(usb->usbdev, 4), + usb->intr_urb->transfer_buffer, 2*sizeof(u16), + go7007_usb_readinterrupt_complete, go); + else + usb_fill_int_urb(usb->intr_urb, usb->usbdev, usb_rcvintpipe(usb->usbdev, 4), usb->intr_urb->transfer_buffer, 2*sizeof(u16), go7007_usb_readinterrupt_complete, go, 8); -- cgit v0.10.2 From 146d35b00db270054378de17ca33eb54b0b78311 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 12 Oct 2011 06:58:44 -0300 Subject: [media] V4L spec: fix typo and missing CAP_RDS documentation For some reason the V4L2_TUNER_CAP_RDS_CONTROLS/BLOCK_IO capabilities were never documented in the proper table. In addition, then RDS interface section incorrectly referred to them as V4L2_TUNER_SUB_RDS_... instead of CAP_RDS_... This is now fixed. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab diff --git a/Documentation/DocBook/media/v4l/dev-rds.xml b/Documentation/DocBook/media/v4l/dev-rds.xml index 2427f54..7644b2e 100644 --- a/Documentation/DocBook/media/v4l/dev-rds.xml +++ b/Documentation/DocBook/media/v4l/dev-rds.xml @@ -29,10 +29,10 @@ returned by the &VIDIOC-QUERYCAP; ioctl. Any tuner that supports RDS will set the V4L2_TUNER_CAP_RDS flag in the capability field of &v4l2-tuner;. If the driver only passes RDS blocks without interpreting the data -the V4L2_TUNER_SUB_RDS_BLOCK_IO flag has to be +the V4L2_TUNER_CAP_RDS_BLOCK_IO flag has to be set, see Reading RDS data. For future use the -flag V4L2_TUNER_SUB_RDS_CONTROLS has also been +flag V4L2_TUNER_CAP_RDS_CONTROLS has also been defined. However, a driver for a radio tuner with this capability does not yet exist, so if you are planning to write such a driver you should discuss this on the linux-media mailing list: &v4l-ml;. @@ -52,9 +52,9 @@ field of &v4l2-modulator;. In order to enable the RDS transmission one must set the V4L2_TUNER_SUB_RDS bit in the txsubchans field of &v4l2-modulator;. If the driver only passes RDS blocks without interpreting the data -the V4L2_TUNER_SUB_RDS_BLOCK_IO flag has to be set. If the +the V4L2_TUNER_CAP_RDS_BLOCK_IO flag has to be set. If the tuner is capable of handling RDS entities like program identification codes and radio -text, the flag V4L2_TUNER_SUB_RDS_CONTROLS should be set, +text, the flag V4L2_TUNER_CAP_RDS_CONTROLS should be set, see Writing RDS data and FM Transmitter Control Reference.
diff --git a/Documentation/DocBook/media/v4l/vidioc-g-tuner.xml b/Documentation/DocBook/media/v4l/vidioc-g-tuner.xml index bd98c73..b23a4b0 100644 --- a/Documentation/DocBook/media/v4l/vidioc-g-tuner.xml +++ b/Documentation/DocBook/media/v4l/vidioc-g-tuner.xml @@ -318,6 +318,16 @@ standard. RDS capture is supported. This capability is only valid for radio tuners. + + V4L2_TUNER_CAP_RDS_BLOCK_IO + 0x0100 + The RDS data is passed as unparsed RDS blocks. + + + V4L2_TUNER_CAP_RDS_CONTROLS + 0x0200 + The RDS data is parsed by the hardware and set via controls. + -- cgit v0.10.2 From 0fb6ec6b1c185a1d99bf238880cc265d72ab111b Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Mon, 7 Nov 2011 08:30:20 -0300 Subject: [media] V4L2 Spec: clarify usage of V4L2_FBUF_FLAG_PRIMARY As per discussion during the 2011 V4L-DVB workshop. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab diff --git a/Documentation/DocBook/media/v4l/vidioc-g-fbuf.xml b/Documentation/DocBook/media/v4l/vidioc-g-fbuf.xml index 0557182..109d729 100644 --- a/Documentation/DocBook/media/v4l/vidioc-g-fbuf.xml +++ b/Documentation/DocBook/media/v4l/vidioc-g-fbuf.xml @@ -295,7 +295,8 @@ set this field to zero. The device is capable of non-destructive overlays. When the driver clears this flag, only destructive overlays are supported. There are no drivers yet which support both destructive and -non-destructive overlays. +non-destructive overlays. Video Output Overlays are in practice always +non-destructive. V4L2_FBUF_CAP_CHROMAKEY @@ -356,7 +357,9 @@ with the chroma-key colors are replaced by video pixels, which is exactly opposi V4L2_FBUF_FLAG_PRIMARY 0x0001 The framebuffer is the primary graphics surface. -In other words, the overlay is destructive. [?] +In other words, the overlay is destructive. This flag is typically set by any +driver that doesn't have the V4L2_FBUF_CAP_EXTERNOVERLAY +capability and it is cleared otherwise. V4L2_FBUF_FLAG_OVERLAY @@ -366,9 +369,8 @@ size as the capture. [?] The purpose of -V4L2_FBUF_FLAG_PRIMARY and V4L2_FBUF_FLAG_OVERLAY was never quite clear. -Most drivers seem to ignore these flags. For compatibility with the +Most drivers seem to ignore this flag. For compatibility with the bttv driver applications should set the V4L2_FBUF_FLAG_OVERLAY flag. -- cgit v0.10.2 From 43599f31ab93bc2c17db615be20ce56261392292 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Mon, 7 Nov 2011 12:44:28 -0300 Subject: [media] v4l2 framework doc: clarify locking high-latency devices. Thanks to Hans de Goede for our discussions on this topic. Signed-off-by: Hans Verkuil Thanks-to: Hans de Goede Signed-off-by: Mauro Carvalho Chehab diff --git a/Documentation/video4linux/v4l2-framework.txt b/Documentation/video4linux/v4l2-framework.txt index f8dcabf..659b2ba 100644 --- a/Documentation/video4linux/v4l2-framework.txt +++ b/Documentation/video4linux/v4l2-framework.txt @@ -612,6 +612,12 @@ You can set a pointer to a mutex_lock in struct video_device. Usually this will be either a top-level mutex or a mutex per device node. If you want finer-grained locking then you have to set it to NULL and do you own locking. +It is up to the driver developer to decide which method to use. However, if +your driver has high-latency operations (for example, changing the exposure +of a USB webcam might take a long time), then you might be better off with +doing your own locking if you want to allow the user to do other things with +the device while waiting for the high-latency command to finish. + If a lock is specified then all file operations will be serialized on that lock. If you use videobuf then you must pass the same lock to the videobuf queue initialize function: if videobuf has to wait for a frame to arrive, then @@ -619,6 +625,11 @@ it will temporarily unlock the lock and relock it afterwards. If your driver also waits in the code, then you should do the same to allow other processes to access the device node while the first process is waiting for something. +In the case of videobuf2 you will need to implement the wait_prepare and +wait_finish callbacks to unlock/lock if applicable. In particular, if you use +the lock in struct video_device then you must unlock/lock this mutex in +wait_prepare and wait_finish. + The implementation of a hotplug disconnect should also take the lock before calling v4l2_device_disconnect. -- cgit v0.10.2 From b698c784bfacc909b05e043d8fca08281fe154bb Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 9 Nov 2011 10:53:01 -0300 Subject: [media] V4L2 spec: fix the description of V4L2_FBUF_CAP_SRC_CHROMAKEY V4L2_FBUF_CAP_SRC_CHROMAKEY is the opposite of V4L2_FBUF_CAP_CHROMAKEY, but according to the documentation it was the same. The terms 'video' and 'framebuffer' were accidentally swapped in the text. Signed-off-by: Hans Verkuil CC: Vaibhav Hiremath Signed-off-by: Mauro Carvalho Chehab diff --git a/Documentation/DocBook/media/v4l/vidioc-g-fbuf.xml b/Documentation/DocBook/media/v4l/vidioc-g-fbuf.xml index 109d729..93817f3 100644 --- a/Documentation/DocBook/media/v4l/vidioc-g-fbuf.xml +++ b/Documentation/DocBook/media/v4l/vidioc-g-fbuf.xml @@ -340,8 +340,8 @@ blending makes no sense for destructive overlays. V4L2_FBUF_CAP_SRC_CHROMAKEY 0x0080 - The device supports Source Chroma-keying. Framebuffer pixels -with the chroma-key colors are replaced by video pixels, which is exactly opposite of + The device supports Source Chroma-keying. Video pixels +with the chroma-key colors are replaced by framebuffer pixels, which is exactly opposite of V4L2_FBUF_CAP_CHROMAKEY -- cgit v0.10.2 From 75c1ca364d0d5d70ad12c5dac40bbe6598624cab Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 23 Nov 2011 02:45:40 -0300 Subject: [media] radio: NUL terminate a user string We pass this to fm_tx_set_radio_text() which expects a NUL terminated string. Signed-off-by: Dan Carpenter Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/radio/wl128x/fmdrv_v4l2.c b/drivers/media/radio/wl128x/fmdrv_v4l2.c index 4f5c43d..077d369 100644 --- a/drivers/media/radio/wl128x/fmdrv_v4l2.c +++ b/drivers/media/radio/wl128x/fmdrv_v4l2.c @@ -84,6 +84,7 @@ static ssize_t fm_v4l2_fops_write(struct file *file, const char __user * buf, struct fmdev *fmdev; ret = copy_from_user(&rds, buf, sizeof(rds)); + rds.text[sizeof(rds.text) - 1] = '\0'; fmdbg("(%d)type: %d, text %s, af %d\n", ret, rds.text_type, rds.text, rds.af_freq); if (ret) -- cgit v0.10.2 From 67114fe6103183190fb0a24f58e5695a80beb2ec Mon Sep 17 00:00:00 2001 From: Thomas Meyer Date: Thu, 17 Nov 2011 23:43:40 +0100 Subject: nfsd4: Use kmemdup rather than duplicating its implementation The semantic patch that makes this change is available in scripts/coccinelle/api/memdup.cocci. Signed-off-by: Thomas Meyer Signed-off-by: J. Bruce Fields diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index a84978c..6ab6779 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -986,12 +986,11 @@ static struct nfs4_client *alloc_client(struct xdr_netobj name) clp = kzalloc(sizeof(struct nfs4_client), GFP_KERNEL); if (clp == NULL) return NULL; - clp->cl_name.data = kmalloc(name.len, GFP_KERNEL); + clp->cl_name.data = kmemdup(name.data, name.len, GFP_KERNEL); if (clp->cl_name.data == NULL) { kfree(clp); return NULL; } - memcpy(clp->cl_name.data, name.data, name.len); clp->cl_name.len = name.len; return clp; } diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index b6fa792..0ec5a1b 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -215,10 +215,9 @@ defer_free(struct nfsd4_compoundargs *argp, static char *savemem(struct nfsd4_compoundargs *argp, __be32 *p, int nbytes) { if (p == argp->tmp) { - p = kmalloc(nbytes, GFP_KERNEL); + p = kmemdup(argp->tmp, nbytes, GFP_KERNEL); if (!p) return NULL; - memcpy(p, argp->tmp, nbytes); } else { BUG_ON(p != argp->tmpp); argp->tmpp = NULL; -- cgit v0.10.2 From 87d466e503ab1e071eac4bd89c46eb3cb53246a1 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 24 Nov 2011 05:06:21 -0300 Subject: [media] staging/media: lirc_imon: add a __user annotation This silences the following Sparse warnings: lirc_imon.c:404:32: warning: incorrect type in argument 1 (different address spaces) lirc_imon.c:404:32: expected void const [noderef] * lirc_imon.c:404:32: got char const *buf lirc_imon.c:117:28: warning: incorrect type in initializer (incompatible argument 2 (different address spaces)) lirc_imon.c:117:28: expected long ( *write )( ... ) lirc_imon.c:117:28: got long ( static [toplevel] * )( ... ) Signed-off-by: Dan Carpenter Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/staging/media/lirc/lirc_imon.c b/drivers/staging/media/lirc/lirc_imon.c index f5308d5..c1654b1 100644 --- a/drivers/staging/media/lirc/lirc_imon.c +++ b/drivers/staging/media/lirc/lirc_imon.c @@ -63,7 +63,7 @@ static int display_open(struct inode *inode, struct file *file); static int display_close(struct inode *inode, struct file *file); /* VFD write operation */ -static ssize_t vfd_write(struct file *file, const char *buf, +static ssize_t vfd_write(struct file *file, const char __user *buf, size_t n_bytes, loff_t *pos); /* LIRC driver function prototypes */ @@ -369,7 +369,7 @@ static int send_packet(struct imon_context *context) * than 32 bytes are provided spaces will be appended to * generate a full screen. */ -static ssize_t vfd_write(struct file *file, const char *buf, +static ssize_t vfd_write(struct file *file, const char __user *buf, size_t n_bytes, loff_t *pos) { int i; -- cgit v0.10.2 From d95d7b91b4c6e3dfe94c07cd04993f60c887073d Mon Sep 17 00:00:00 2001 From: Janusz Krzysztofik Date: Thu, 24 Nov 2011 19:16:35 -0300 Subject: [media] V4L: omap1_camera: fix missing include Otherwise compilation breaks with: ... after apparently no longer included recursively from other header files. Signed-off-by: Janusz Krzysztofik Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/omap1_camera.c b/drivers/media/video/omap1_camera.c index e87ae2f..6a6cf38 100644 --- a/drivers/media/video/omap1_camera.c +++ b/drivers/media/video/omap1_camera.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include -- cgit v0.10.2 From 75f064f220bde2fab9e932b27eee8372b65372c9 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 28 Nov 2011 19:38:54 -0200 Subject: [media] tm6000: Add a few missing bits to alsa There are some properties found on em28xx, but not on tm6000. Add them, in order to be more consistent. Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/tm6000/tm6000-alsa.c b/drivers/media/video/tm6000/tm6000-alsa.c index 7d675c7..ddffd67 100644 --- a/drivers/media/video/tm6000/tm6000-alsa.c +++ b/drivers/media/video/tm6000/tm6000-alsa.c @@ -146,20 +146,21 @@ static int dsp_buffer_alloc(struct snd_pcm_substream *substream, int size) #define DEFAULT_FIFO_SIZE 4096 static struct snd_pcm_hardware snd_tm6000_digital_hw = { - .info = SNDRV_PCM_INFO_MMAP | + .info = SNDRV_PCM_INFO_BATCH | + SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_MMAP_VALID, .formats = SNDRV_PCM_FMTBIT_S16_LE, - .rates = SNDRV_PCM_RATE_CONTINUOUS, + .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_KNOT, .rate_min = 48000, .rate_max = 48000, .channels_min = 2, .channels_max = 2, .period_bytes_min = 64, .period_bytes_max = 12544, - .periods_min = 1, + .periods_min = 2, .periods_max = 98, .buffer_bytes_max = 62720 * 8, }; @@ -181,6 +182,7 @@ static int snd_tm6000_pcm_open(struct snd_pcm_substream *substream) chip->substream = substream; runtime->hw = snd_tm6000_digital_hw; + snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS); return 0; _error: @@ -347,9 +349,13 @@ static int snd_tm6000_card_trigger(struct snd_pcm_substream *substream, int cmd) int err = 0; switch (cmd) { + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: /* fall through */ + case SNDRV_PCM_TRIGGER_RESUME: /* fall through */ case SNDRV_PCM_TRIGGER_START: atomic_set(&core->stream_started, 1); break; + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: /* fall through */ + case SNDRV_PCM_TRIGGER_SUSPEND: /* fall through */ case SNDRV_PCM_TRIGGER_STOP: atomic_set(&core->stream_started, 0); break; @@ -371,6 +377,14 @@ static snd_pcm_uframes_t snd_tm6000_pointer(struct snd_pcm_substream *substream) return chip->buf_pos; } +static struct page *snd_pcm_get_vmalloc_page(struct snd_pcm_substream *subs, + unsigned long offset) +{ + void *pageptr = subs->runtime->dma_area + offset; + + return vmalloc_to_page(pageptr); +} + /* * operators */ @@ -383,6 +397,7 @@ static struct snd_pcm_ops snd_tm6000_pcm_ops = { .prepare = snd_tm6000_prepare, .trigger = snd_tm6000_card_trigger, .pointer = snd_tm6000_pointer, + .page = snd_pcm_get_vmalloc_page, }; /* -- cgit v0.10.2 From 32f6f3ac5468bbbe0263d29daa16f38d04c2274f Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 24 Nov 2011 12:20:12 -0300 Subject: [media] tm6000: Fix tm6010 audio standard selection A V4L2 standards mask may contain several standards. A more restricted mask with just one standard is used when user needs to bind to an specific standard that can't be auto-detect among a more generic mask. So, Improve the autodetection logic to detect the correct audio standard most of the time. Based on a patch made by Dmitri Belimov . Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/tm6000/tm6000-core.c b/drivers/media/video/tm6000/tm6000-core.c index 9783616..55d097e 100644 --- a/drivers/media/video/tm6000/tm6000-core.c +++ b/drivers/media/video/tm6000/tm6000-core.c @@ -696,11 +696,13 @@ int tm6000_set_audio_rinput(struct tm6000_core *dev) if (dev->dev_type == TM6010) { /* Audio crossbar setting, default SIF1 */ u8 areg_f0; + u8 areg_07 = 0x10; switch (dev->rinput.amux) { case TM6000_AMUX_SIF1: case TM6000_AMUX_SIF2: areg_f0 = 0x03; + areg_07 = 0x30; break; case TM6000_AMUX_ADC1: areg_f0 = 0x00; @@ -720,6 +722,9 @@ int tm6000_set_audio_rinput(struct tm6000_core *dev) /* Set audio input crossbar */ tm6000_set_reg_mask(dev, TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG, areg_f0, 0x0f); + /* Mux overflow workaround */ + tm6000_set_reg_mask(dev, TM6010_REQ07_R07_OUTPUT_CONTROL, + areg_07, 0xf0); } else { u8 areg_eb; /* Audio setting, default LINE1 */ diff --git a/drivers/media/video/tm6000/tm6000-stds.c b/drivers/media/video/tm6000/tm6000-stds.c index 9a4145d..9dc0831 100644 --- a/drivers/media/video/tm6000/tm6000-stds.c +++ b/drivers/media/video/tm6000/tm6000-stds.c @@ -361,82 +361,51 @@ static int tm6000_set_audio_std(struct tm6000_core *dev) return 0; } - switch (tm6010_a_mode) { + /* + * STD/MN shouldn't be affected by tm6010_a_mode, as there's just one + * audio standard for each V4L2_STD type. + */ + if ((dev->norm & V4L2_STD_NTSC) == V4L2_STD_NTSC_M_KR) { + areg_05 |= 0x04; + } else if ((dev->norm & V4L2_STD_NTSC) == V4L2_STD_NTSC_M_JP) { + areg_05 |= 0x43; + } else if (dev->norm & V4L2_STD_MN) { + areg_05 |= 0x22; + } else switch (tm6010_a_mode) { /* auto */ case 0: - switch (dev->norm) { - case V4L2_STD_NTSC_M_KR: + if ((dev->norm & V4L2_STD_SECAM) == V4L2_STD_SECAM_L) areg_05 |= 0x00; - break; - case V4L2_STD_NTSC_M_JP: - areg_05 |= 0x40; - break; - case V4L2_STD_NTSC_M: - case V4L2_STD_PAL_M: - case V4L2_STD_PAL_N: - areg_05 |= 0x20; - break; - case V4L2_STD_PAL_Nc: - areg_05 |= 0x60; - break; - case V4L2_STD_SECAM_L: - areg_05 |= 0x00; - break; - case V4L2_STD_DK: + else /* Other PAL/SECAM standards */ areg_05 |= 0x10; - break; - } break; /* A2 */ case 1: - switch (dev->norm) { - case V4L2_STD_B: - case V4L2_STD_GH: - areg_05 = 0x05; - break; - case V4L2_STD_DK: + if (dev->norm & V4L2_STD_DK) areg_05 = 0x09; - break; - } + else + areg_05 = 0x05; break; /* NICAM */ case 2: - switch (dev->norm) { - case V4L2_STD_B: - case V4L2_STD_GH: - areg_05 = 0x07; - break; - case V4L2_STD_DK: + if (dev->norm & V4L2_STD_DK) { areg_05 = 0x06; - break; - case V4L2_STD_PAL_I: + } else if (dev->norm & V4L2_STD_PAL_I) { areg_05 = 0x08; - break; - case V4L2_STD_SECAM_L: + } else if (dev->norm & V4L2_STD_SECAM_L) { areg_05 = 0x0a; areg_02 = 0x02; - break; + } else { + areg_05 = 0x07; } nicam_flag = 1; break; /* other */ case 3: - switch (dev->norm) { - /* DK3_A2 */ - case V4L2_STD_DK: + if (dev->norm & V4L2_STD_DK) { areg_05 = 0x0b; - break; - /* Korea */ - case V4L2_STD_NTSC_M_KR: - areg_05 = 0x04; - break; - /* EIAJ */ - case V4L2_STD_NTSC_M_JP: - areg_05 = 0x03; - break; - default: + } else { areg_05 = 0x02; - break; } break; } @@ -557,10 +526,16 @@ int tm6000_set_standard(struct tm6000_core *dev) case TM6000_AMUX_ADC1: tm6000_set_reg_mask(dev, TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG, 0x00, 0x0f); + /* Mux overflow workaround */ + tm6000_set_reg_mask(dev, TM6010_REQ07_R07_OUTPUT_CONTROL, + 0x10, 0xf0); break; case TM6000_AMUX_ADC2: tm6000_set_reg_mask(dev, TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG, 0x08, 0x0f); + /* Mux overflow workaround */ + tm6000_set_reg_mask(dev, TM6010_REQ07_R07_OUTPUT_CONTROL, + 0x10, 0xf0); break; case TM6000_AMUX_SIF1: reg_08_e2 |= 0x02; @@ -570,6 +545,9 @@ int tm6000_set_standard(struct tm6000_core *dev) tm6000_set_reg(dev, TM6010_REQ08_RE4_ADC_IN2_SEL, 0xf3); tm6000_set_reg_mask(dev, TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG, 0x02, 0x0f); + /* Mux overflow workaround */ + tm6000_set_reg_mask(dev, TM6010_REQ07_R07_OUTPUT_CONTROL, + 0x30, 0xf0); break; case TM6000_AMUX_SIF2: reg_08_e2 |= 0x02; @@ -579,6 +557,9 @@ int tm6000_set_standard(struct tm6000_core *dev) tm6000_set_reg(dev, TM6010_REQ08_RE4_ADC_IN2_SEL, 0xf7); tm6000_set_reg_mask(dev, TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG, 0x02, 0x0f); + /* Mux overflow workaround */ + tm6000_set_reg_mask(dev, TM6010_REQ07_R07_OUTPUT_CONTROL, + 0x30, 0xf0); break; default: break; -- cgit v0.10.2 From 078a68c11fe0580a23754fac25a6d9896719278e Mon Sep 17 00:00:00 2001 From: Stefan Ringel Date: Mon, 28 Nov 2011 15:46:16 -0300 Subject: [media] tm6000: remove experimental depends Signed-off-by: Stefan Ringel Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/tm6000/Kconfig b/drivers/media/video/tm6000/Kconfig index 114eec8..a43b77a 100644 --- a/drivers/media/video/tm6000/Kconfig +++ b/drivers/media/video/tm6000/Kconfig @@ -1,6 +1,6 @@ config VIDEO_TM6000 tristate "TV Master TM5600/6000/6010 driver" - depends on VIDEO_DEV && I2C && INPUT && RC_CORE && USB && EXPERIMENTAL + depends on VIDEO_DEV && I2C && INPUT && RC_CORE && USB select VIDEO_TUNER select MEDIA_TUNER_XC2028 select MEDIA_TUNER_XC5000 @@ -16,7 +16,7 @@ config VIDEO_TM6000 config VIDEO_TM6000_ALSA tristate "TV Master TM5600/6000/6010 audio support" - depends on VIDEO_TM6000 && SND && EXPERIMENTAL + depends on VIDEO_TM6000 && SND select SND_PCM ---help--- This is a video4linux driver for direct (DMA) audio for @@ -27,7 +27,7 @@ config VIDEO_TM6000_ALSA config VIDEO_TM6000_DVB tristate "DVB Support for tm6000 based TV cards" - depends on VIDEO_TM6000 && DVB_CORE && USB && EXPERIMENTAL + depends on VIDEO_TM6000 && DVB_CORE && USB select DVB_ZL10353 ---help--- This adds support for DVB cards based on the tm5600/tm6000 chip. -- cgit v0.10.2 From c00ecc97bc638919ff35117290b4fab01354e8d7 Mon Sep 17 00:00:00 2001 From: Stefan Ringel Date: Mon, 28 Nov 2011 15:46:17 -0300 Subject: [media] tm6000: bugfix at tm6000_set_reg_mask() register setting Signed-off-by: Stefan Ringel Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/tm6000/tm6000-core.c b/drivers/media/video/tm6000/tm6000-core.c index 55d097e..5d7d045 100644 --- a/drivers/media/video/tm6000/tm6000-core.c +++ b/drivers/media/video/tm6000/tm6000-core.c @@ -125,14 +125,14 @@ int tm6000_set_reg_mask(struct tm6000_core *dev, u8 req, u16 value, u8 new_index; rc = tm6000_read_write_usb(dev, USB_DIR_IN | USB_TYPE_VENDOR, req, - value, index, buf, 1); + value, 0, buf, 1); if (rc < 0) return rc; new_index = (buf[0] & ~mask) | (index & mask); - if (new_index == index) + if (new_index == buf[0]) return 0; return tm6000_read_write_usb(dev, USB_DIR_OUT | USB_TYPE_VENDOR, -- cgit v0.10.2 From 8159c184cf58ac78fc868d776fa2062d1162b6e5 Mon Sep 17 00:00:00 2001 From: Stefan Ringel Date: Mon, 28 Nov 2011 15:46:18 -0300 Subject: [media] tm6000: bugfix at interrupt reset Signed-off-by: Stefan Ringel Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/tm6000/tm6000-core.c b/drivers/media/video/tm6000/tm6000-core.c index 5d7d045..b16b46a 100644 --- a/drivers/media/video/tm6000/tm6000-core.c +++ b/drivers/media/video/tm6000/tm6000-core.c @@ -599,55 +599,6 @@ int tm6000_init(struct tm6000_core *dev) return rc; } -int tm6000_reset(struct tm6000_core *dev) -{ - int pipe; - int err; - - msleep(500); - - err = usb_set_interface(dev->udev, dev->isoc_in.bInterfaceNumber, 0); - if (err < 0) { - tm6000_err("failed to select interface %d, alt. setting 0\n", - dev->isoc_in.bInterfaceNumber); - return err; - } - - err = usb_reset_configuration(dev->udev); - if (err < 0) { - tm6000_err("failed to reset configuration\n"); - return err; - } - - if ((dev->quirks & TM6000_QUIRK_NO_USB_DELAY) == 0) - msleep(5); - - /* - * Not all devices have int_in defined - */ - if (!dev->int_in.endp) - return 0; - - err = usb_set_interface(dev->udev, dev->isoc_in.bInterfaceNumber, 2); - if (err < 0) { - tm6000_err("failed to select interface %d, alt. setting 2\n", - dev->isoc_in.bInterfaceNumber); - return err; - } - - msleep(5); - - pipe = usb_rcvintpipe(dev->udev, - dev->int_in.endp->desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK); - - err = usb_clear_halt(dev->udev, pipe); - if (err < 0) { - tm6000_err("usb_clear_halt failed: %d\n", err); - return err; - } - - return 0; -} int tm6000_set_audio_bitrate(struct tm6000_core *dev, int bitrate) { diff --git a/drivers/media/video/tm6000/tm6000-video.c b/drivers/media/video/tm6000/tm6000-video.c index 1e5ace0..4db3535 100644 --- a/drivers/media/video/tm6000/tm6000-video.c +++ b/drivers/media/video/tm6000/tm6000-video.c @@ -1609,12 +1609,25 @@ static int tm6000_release(struct file *file) tm6000_uninit_isoc(dev); + /* Stop interrupt USB pipe */ + tm6000_ir_int_stop(dev); + + usb_reset_configuration(dev->udev); + + if (&dev->int_in) + usb_set_interface(dev->udev, + dev->isoc_in.bInterfaceNumber, + 2); + else + usb_set_interface(dev->udev, + dev->isoc_in.bInterfaceNumber, + 0); + + /* Start interrupt USB pipe */ + tm6000_ir_int_start(dev); + if (!fh->radio) videobuf_mmap_free(&fh->vb_vidq); - - err = tm6000_reset(dev); - if (err < 0) - dev_err(&vdev->dev, "reset failed: %d\n", err); } kfree(fh); -- cgit v0.10.2 From de2a20baff364b8dd19371acc1dc0b138e0b08b9 Mon Sep 17 00:00:00 2001 From: Stefan Ringel Date: Mon, 28 Nov 2011 15:46:19 -0300 Subject: [media] tm6000: bugfix at bulk transfer Signed-off-by: Stefan Ringel Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/tm6000/tm6000-dvb.c b/drivers/media/video/tm6000/tm6000-dvb.c index 5e6c129..db6a561 100644 --- a/drivers/media/video/tm6000/tm6000-dvb.c +++ b/drivers/media/video/tm6000/tm6000-dvb.c @@ -89,9 +89,19 @@ static void tm6000_urb_received(struct urb *urb) int ret; struct tm6000_core *dev = urb->context; - if (urb->status != 0) + switch (urb->status) { + case 0: + case -ETIMEDOUT: + break; + case -ENOENT: + case -ECONNRESET: + case -ESHUTDOWN: + return; + default: print_err_status(dev, 0, urb->status); - else if (urb->actual_length > 0) + } + + if (urb->actual_length > 0) dvb_dmx_swfilter(&dev->dvb->demux, urb->transfer_buffer, urb->actual_length); @@ -151,7 +161,7 @@ static int tm6000_start_stream(struct tm6000_core *dev) printk(KERN_ERR "tm6000: pipe resetted\n"); /* mutex_lock(&tm6000_driver.open_close_mutex); */ - ret = usb_submit_urb(dvb->bulk_urb, GFP_KERNEL); + ret = usb_submit_urb(dvb->bulk_urb, GFP_ATOMIC); /* mutex_unlock(&tm6000_driver.open_close_mutex); */ if (ret) { -- cgit v0.10.2 From edcfdd919a1c8afbf500be0dbfa9b68f40b4c219 Mon Sep 17 00:00:00 2001 From: Stefan Ringel Date: Mon, 28 Nov 2011 15:46:20 -0300 Subject: [media] tm6000: bugfix data check beholder use a map with 3 bytes, but many rc maps have 2 bytes, so I add a workaround for beholder rc. Signed-off-by: Stefan Ringel Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/tm6000/tm6000-input.c b/drivers/media/video/tm6000/tm6000-input.c index 405d127..ae7772e 100644 --- a/drivers/media/video/tm6000/tm6000-input.c +++ b/drivers/media/video/tm6000/tm6000-input.c @@ -178,9 +178,21 @@ static int default_polling_getkey(struct tm6000_IR *ir, poll_result->rc_data = ir->urb_data[0]; break; case RC_TYPE_NEC: - if (ir->urb_data[1] == ((ir->key_addr >> 8) & 0xff)) { + switch (dev->model) { + case 10: + case 11: + case 14: + case 15: + if (ir->urb_data[1] == + ((ir->key_addr >> 8) & 0xff)) { + poll_result->rc_data = + ir->urb_data[0] + | ir->urb_data[1] << 8; + } + break; + default: poll_result->rc_data = ir->urb_data[0] - | ir->urb_data[1] << 8; + | ir->urb_data[1] << 8; } break; default: @@ -238,8 +250,6 @@ static void tm6000_ir_handle_key(struct tm6000_IR *ir) return; } - dprintk("ir->get_key result data=%04x\n", poll_result.rc_data); - if (ir->pwled) { if (ir->pwledcnt >= PWLED_OFF) { ir->pwled = 0; @@ -250,6 +260,7 @@ static void tm6000_ir_handle_key(struct tm6000_IR *ir) } if (ir->key) { + dprintk("ir->get_key result data=%04x\n", poll_result.rc_data); rc_keydown(ir->rc, poll_result.rc_data, 0); ir->key = 0; ir->pwled = 1; @@ -333,7 +344,7 @@ int tm6000_ir_int_start(struct tm6000_core *dev) ir->int_urb->transfer_buffer, size, tm6000_ir_urb_received, dev, dev->int_in.endp->desc.bInterval); - err = usb_submit_urb(ir->int_urb, GFP_KERNEL); + err = usb_submit_urb(ir->int_urb, GFP_ATOMIC); if (err) { kfree(ir->int_urb->transfer_buffer); usb_free_urb(ir->int_urb); -- cgit v0.10.2 From 36d36b884c745c507d9b3f60eb42925749f7d758 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 28 Nov 2011 21:58:54 -0200 Subject: [media] tm6000: Warning cleanup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit drivers/media/video/tm6000/tm6000-video.c: In function ‘tm6000_release’: drivers/media/video/tm6000/tm6000-video.c:1608:7: warning: unused variable ‘err’ [-Wunused-variable] Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/tm6000/tm6000-video.c b/drivers/media/video/tm6000/tm6000-video.c index 4db3535..436fd67 100644 --- a/drivers/media/video/tm6000/tm6000-video.c +++ b/drivers/media/video/tm6000/tm6000-video.c @@ -1605,8 +1605,6 @@ static int tm6000_release(struct file *file) res_free(dev, fh); if (!dev->users) { - int err; - tm6000_uninit_isoc(dev); /* Stop interrupt USB pipe */ -- cgit v0.10.2 From 15a295ec31fbef374ebda5f286a908e498a4579a Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 29 Nov 2011 11:35:55 -0300 Subject: [media] tm6000: Fix IR register names IR registers 0xd9 to 0xdf were badly named, making harder to check what's the register accessed at the RC code. Fix the name convention. No functional changes on this patch. Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/tm6000/tm6000-core.c b/drivers/media/video/tm6000/tm6000-core.c index b16b46a..6c1fdb5 100644 --- a/drivers/media/video/tm6000/tm6000-core.c +++ b/drivers/media/video/tm6000/tm6000-core.c @@ -536,16 +536,16 @@ static struct reg_init tm6010_init_tab[] = { { TM6010_REQ05_R18_IMASK7, 0x00 }, - { TM6010_REQ07_RD8_IR_LEADER1, 0xaa }, - { TM6010_REQ07_RD8_IR_LEADER0, 0x30 }, - { TM6010_REQ07_RD8_IR_PULSE_CNT1, 0x20 }, - { TM6010_REQ07_RD8_IR_PULSE_CNT0, 0xd0 }, + { TM6010_REQ07_RDC_IR_LEADER1, 0xaa }, + { TM6010_REQ07_RDD_IR_LEADER0, 0x30 }, + { TM6010_REQ07_RDE_IR_PULSE_CNT1, 0x20 }, + { TM6010_REQ07_RDF_IR_PULSE_CNT0, 0xd0 }, { REQ_04_EN_DISABLE_MCU_INT, 0x02, 0x00 }, { TM6010_REQ07_RD8_IR, 0x2f }, /* set remote wakeup key:any key wakeup */ { TM6010_REQ07_RE5_REMOTE_WAKEUP, 0xfe }, - { TM6010_REQ07_RD8_IR_WAKEUP_SEL, 0xff }, + { TM6010_REQ07_RDA_IR_WAKEUP_SEL, 0xff }, }; int tm6000_init(struct tm6000_core *dev) diff --git a/drivers/media/video/tm6000/tm6000-input.c b/drivers/media/video/tm6000/tm6000-input.c index ae7772e..8b07b72 100644 --- a/drivers/media/video/tm6000/tm6000-input.c +++ b/drivers/media/video/tm6000/tm6000-input.c @@ -100,17 +100,17 @@ static int tm6000_ir_config(struct tm6000_IR *ir) case RC_TYPE_NEC: /* Setup IR decoder for NEC standard 12MHz system clock */ /* IR_LEADER_CNT = 0.9ms */ - tm6000_set_reg(dev, TM6010_REQ07_RD8_IR_LEADER1, 0xaa); - tm6000_set_reg(dev, TM6010_REQ07_RD8_IR_LEADER0, 0x30); + tm6000_set_reg(dev, TM6010_REQ07_RDC_IR_LEADER1, 0xaa); + tm6000_set_reg(dev, TM6010_REQ07_RDD_IR_LEADER0, 0x30); /* IR_PULSE_CNT = 0.7ms */ - tm6000_set_reg(dev, TM6010_REQ07_RD8_IR_PULSE_CNT1, 0x20); - tm6000_set_reg(dev, TM6010_REQ07_RD8_IR_PULSE_CNT0, 0xd0); + tm6000_set_reg(dev, TM6010_REQ07_RDE_IR_PULSE_CNT1, 0x20); + tm6000_set_reg(dev, TM6010_REQ07_RDF_IR_PULSE_CNT0, 0xd0); /* Remote WAKEUP = enable */ tm6000_set_reg(dev, TM6010_REQ07_RE5_REMOTE_WAKEUP, 0xfe); /* IR_WKUP_SEL = Low byte in decoded IR data */ - tm6000_set_reg(dev, TM6010_REQ07_RD8_IR_WAKEUP_SEL, 0xff); + tm6000_set_reg(dev, TM6010_REQ07_RDA_IR_WAKEUP_SEL, 0xff); /* IR_WKU_ADD code */ - tm6000_set_reg(dev, TM6010_REQ07_RD8_IR_WAKEUP_ADD, 0xff); + tm6000_set_reg(dev, TM6010_REQ07_RDB_IR_WAKEUP_ADD, 0xff); tm6000_flash_led(dev, 0); msleep(100); tm6000_flash_led(dev, 1); diff --git a/drivers/media/video/tm6000/tm6000-regs.h b/drivers/media/video/tm6000/tm6000-regs.h index 7f491b6..a38c251 100644 --- a/drivers/media/video/tm6000/tm6000-regs.h +++ b/drivers/media/video/tm6000/tm6000-regs.h @@ -284,19 +284,19 @@ enum { /* ONLY for TM6010 */ #define TM6010_REQ07_RD8_IR 0x07, 0xd8 /* ONLY for TM6010 */ -#define TM6010_REQ07_RD8_IR_BSIZE 0x07, 0xd9 +#define TM6010_REQ07_RD9_IR_BSIZE 0x07, 0xd9 /* ONLY for TM6010 */ -#define TM6010_REQ07_RD8_IR_WAKEUP_SEL 0x07, 0xda +#define TM6010_REQ07_RDA_IR_WAKEUP_SEL 0x07, 0xda /* ONLY for TM6010 */ -#define TM6010_REQ07_RD8_IR_WAKEUP_ADD 0x07, 0xdb +#define TM6010_REQ07_RDB_IR_WAKEUP_ADD 0x07, 0xdb /* ONLY for TM6010 */ -#define TM6010_REQ07_RD8_IR_LEADER1 0x07, 0xdc +#define TM6010_REQ07_RDC_IR_LEADER1 0x07, 0xdc /* ONLY for TM6010 */ -#define TM6010_REQ07_RD8_IR_LEADER0 0x07, 0xdd +#define TM6010_REQ07_RDD_IR_LEADER0 0x07, 0xdd /* ONLY for TM6010 */ -#define TM6010_REQ07_RD8_IR_PULSE_CNT1 0x07, 0xde +#define TM6010_REQ07_RDE_IR_PULSE_CNT1 0x07, 0xde /* ONLY for TM6010 */ -#define TM6010_REQ07_RD8_IR_PULSE_CNT0 0x07, 0xdf +#define TM6010_REQ07_RDF_IR_PULSE_CNT0 0x07, 0xdf /* ONLY for TM6010 */ #define TM6010_REQ07_RE0_DVIDEO_SOURCE 0x07, 0xe0 /* ONLY for TM6010 */ -- cgit v0.10.2 From 884b0515dcbcd9e574d385c97f80243805b5b0f3 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 29 Nov 2011 13:33:52 -0300 Subject: [media] tuner-xc2028: Better report signal strength Fix lock bit to better indicate signal strength, from 4096 to 65535. Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/common/tuners/tuner-xc2028.c b/drivers/media/common/tuners/tuner-xc2028.c index 3acbaa0..e531267 100644 --- a/drivers/media/common/tuners/tuner-xc2028.c +++ b/drivers/media/common/tuners/tuner-xc2028.c @@ -891,7 +891,7 @@ static int xc2028_signal(struct dvb_frontend *fe, u16 *strength) /* Frequency is locked */ if (frq_lock == 1) - signal = 32768; + signal = 1 << 11; /* Get SNR of the video signal */ rc = xc2028_get_reg(priv, 0x0040, &signal); -- cgit v0.10.2 From f9fa905bde6f2e8354eee35c08362dded08e3c1e Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 30 Nov 2011 12:58:51 -0300 Subject: [media] tm6000: add IR support for HVR-900H Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/tm6000/tm6000-cards.c b/drivers/media/video/tm6000/tm6000-cards.c index ec2578a..0b54132 100644 --- a/drivers/media/video/tm6000/tm6000-cards.c +++ b/drivers/media/video/tm6000/tm6000-cards.c @@ -351,6 +351,7 @@ static struct tm6000_board tm6000_boards[] = { .tuner_addr = 0xc2 >> 1, .demod_addr = 0x1e >> 1, .type = TM6010, + .ir_codes = RC_MAP_HAUPPAUGE, .caps = { .has_tuner = 1, .has_dvb = 1, -- cgit v0.10.2 From 4a83b0115066ae5a8111938df97231e65d0f88e3 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 29 Nov 2011 11:30:30 -0300 Subject: [media] tm6000: rewrite IR support The IR support were broken on my tests with HVR-900H. Also, there were several issues on the current implementation. This patch is a major rewrite of the IR support for this - Improve debug messages; - Don't do polling for interrrupt based IR; - Add proper support for RC-5 protocol; - Always provide 16 bits for NEC and RC-5; - Fix polling code; - Split polling functions from URB Interrupt ones; - Don't hardcode the XTAL reference for tm6000 IR; - If a URB submit fails, retries after 100ms; - etc. Tested on Hauppauge HVR-900H, with RC-5 and NEC remotes. Issues on IR handling, on this device: - Repeat events aren't detected (neither on NEC or RC-5); - NEC codes are always provided with 16 bits. Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/tm6000/tm6000-core.c b/drivers/media/video/tm6000/tm6000-core.c index 6c1fdb5..fa37b5f 100644 --- a/drivers/media/video/tm6000/tm6000-core.c +++ b/drivers/media/video/tm6000/tm6000-core.c @@ -541,7 +541,7 @@ static struct reg_init tm6010_init_tab[] = { { TM6010_REQ07_RDE_IR_PULSE_CNT1, 0x20 }, { TM6010_REQ07_RDF_IR_PULSE_CNT0, 0xd0 }, { REQ_04_EN_DISABLE_MCU_INT, 0x02, 0x00 }, - { TM6010_REQ07_RD8_IR, 0x2f }, + { TM6010_REQ07_RD8_IR, 0x0f }, /* set remote wakeup key:any key wakeup */ { TM6010_REQ07_RE5_REMOTE_WAKEUP, 0xfe }, diff --git a/drivers/media/video/tm6000/tm6000-input.c b/drivers/media/video/tm6000/tm6000-input.c index 8b07b72..6eaf770 100644 --- a/drivers/media/video/tm6000/tm6000-input.c +++ b/drivers/media/video/tm6000/tm6000-input.c @@ -31,22 +31,25 @@ static unsigned int ir_debug; module_param(ir_debug, int, 0644); -MODULE_PARM_DESC(ir_debug, "enable debug message [IR]"); +MODULE_PARM_DESC(ir_debug, "debug message level"); static unsigned int enable_ir = 1; module_param(enable_ir, int, 0644); MODULE_PARM_DESC(enable_ir, "enable ir (default is enable)"); -/* number of 50ms for ON-OFF-ON power led */ -/* show IR activity */ -#define PWLED_OFF 2 +static unsigned int ir_clock_mhz = 12; +module_param(ir_clock_mhz, int, 0644); +MODULE_PARM_DESC(enable_ir, "ir clock, in MHz"); + +#define URB_SUBMIT_DELAY 100 /* ms - Delay to submit an URB request on retrial and init */ +#define URB_INT_LED_DELAY 100 /* ms - Delay to turn led on again on int mode */ #undef dprintk -#define dprintk(fmt, arg...) \ - if (ir_debug) { \ +#define dprintk(level, fmt, arg...) do {\ + if (ir_debug >= level) \ printk(KERN_DEBUG "%s/ir: " fmt, ir->name , ## arg); \ - } + } while (0) struct tm6000_ir_poll_result { u16 rc_data; @@ -62,20 +65,15 @@ struct tm6000_IR { int polling; struct delayed_work work; u8 wait:1; - u8 key:1; - u8 pwled:1; - u8 pwledcnt; + u8 pwled:2; + u8 submit_urb:1; u16 key_addr; struct urb *int_urb; - u8 *urb_data; - - int (*get_key) (struct tm6000_IR *, struct tm6000_ir_poll_result *); /* IR device properties */ u64 rc_type; }; - void tm6000_ir_wait(struct tm6000_core *dev, u8 state) { struct tm6000_IR *ir = dev->ir; @@ -83,62 +81,84 @@ void tm6000_ir_wait(struct tm6000_core *dev, u8 state) if (!dev->ir) return; + dprintk(2, "%s: %i\n",__func__, ir->wait); + if (state) ir->wait = 1; else ir->wait = 0; } - static int tm6000_ir_config(struct tm6000_IR *ir) { struct tm6000_core *dev = ir->dev; - u8 buf[10]; - int rc; + u32 pulse = 0, leader = 0; + + dprintk(2, "%s\n",__func__); + + /* + * The IR decoder supports RC-5 or NEC, with a configurable timing. + * The timing configuration there is not that accurate, as it uses + * approximate values. The NEC spec mentions a 562.5 unit period, + * and RC-5 uses a 888.8 period. + * Currently, driver assumes a clock provided by a 12 MHz XTAL, but + * a modprobe parameter can adjust it. + * Adjustments are required for other timings. + * It seems that the 900ms timing for NEC is used to detect a RC-5 + * IR, in order to discard such decoding + */ switch (ir->rc_type) { case RC_TYPE_NEC: - /* Setup IR decoder for NEC standard 12MHz system clock */ - /* IR_LEADER_CNT = 0.9ms */ - tm6000_set_reg(dev, TM6010_REQ07_RDC_IR_LEADER1, 0xaa); - tm6000_set_reg(dev, TM6010_REQ07_RDD_IR_LEADER0, 0x30); - /* IR_PULSE_CNT = 0.7ms */ - tm6000_set_reg(dev, TM6010_REQ07_RDE_IR_PULSE_CNT1, 0x20); - tm6000_set_reg(dev, TM6010_REQ07_RDF_IR_PULSE_CNT0, 0xd0); - /* Remote WAKEUP = enable */ - tm6000_set_reg(dev, TM6010_REQ07_RE5_REMOTE_WAKEUP, 0xfe); - /* IR_WKUP_SEL = Low byte in decoded IR data */ - tm6000_set_reg(dev, TM6010_REQ07_RDA_IR_WAKEUP_SEL, 0xff); - /* IR_WKU_ADD code */ - tm6000_set_reg(dev, TM6010_REQ07_RDB_IR_WAKEUP_ADD, 0xff); - tm6000_flash_led(dev, 0); - msleep(100); - tm6000_flash_led(dev, 1); + leader = 900; /* ms */ + pulse = 700; /* ms - the actual value would be 562 */ break; default: - /* hack */ - buf[0] = 0xff; - buf[1] = 0xff; - buf[2] = 0xf2; - buf[3] = 0x2b; - buf[4] = 0x20; - buf[5] = 0x35; - buf[6] = 0x60; - buf[7] = 0x04; - buf[8] = 0xc0; - buf[9] = 0x08; - - rc = tm6000_read_write_usb(dev, USB_DIR_OUT | USB_TYPE_VENDOR | - USB_RECIP_DEVICE, REQ_00_SET_IR_VALUE, 0, 0, buf, 0x0a); - msleep(100); - - if (rc < 0) { - printk(KERN_INFO "IR configuration failed"); - return rc; - } + case RC_TYPE_RC5: + leader = 900; /* ms - from the NEC decoding */ + pulse = 1780; /* ms - The actual value would be 1776 */ break; } + pulse = ir_clock_mhz * pulse; + leader = ir_clock_mhz * leader; + if (ir->rc_type == RC_TYPE_NEC) + leader = leader | 0x8000; + + dprintk(2, "%s: %s, %d MHz, leader = 0x%04x, pulse = 0x%06x \n", + __func__, + (ir->rc_type == RC_TYPE_NEC) ? "NEC" : "RC-5", + ir_clock_mhz, leader, pulse); + + /* Remote WAKEUP = enable, normal mode, from IR decoder output */ + tm6000_set_reg(dev, TM6010_REQ07_RE5_REMOTE_WAKEUP, 0xfe); + + /* Enable IR reception on non-busrt mode */ + tm6000_set_reg(dev, TM6010_REQ07_RD8_IR, 0x2f); + + /* IR_WKUP_SEL = Low byte in decoded IR data */ + tm6000_set_reg(dev, TM6010_REQ07_RDA_IR_WAKEUP_SEL, 0xff); + /* IR_WKU_ADD code */ + tm6000_set_reg(dev, TM6010_REQ07_RDB_IR_WAKEUP_ADD, 0xff); + + tm6000_set_reg(dev, TM6010_REQ07_RDC_IR_LEADER1, leader >> 8); + tm6000_set_reg(dev, TM6010_REQ07_RDD_IR_LEADER0, leader); + + tm6000_set_reg(dev, TM6010_REQ07_RDE_IR_PULSE_CNT1, pulse >> 8); + tm6000_set_reg(dev, TM6010_REQ07_RDF_IR_PULSE_CNT0, pulse); + + if (!ir->polling) + tm6000_set_reg(dev, REQ_04_EN_DISABLE_MCU_INT, 2, 0); + else + tm6000_set_reg(dev, REQ_04_EN_DISABLE_MCU_INT, 2, 1); + msleep(10); + + /* Shows that IR is working via the LED */ + tm6000_flash_led(dev, 0); + msleep(100); + tm6000_flash_led(dev, 1); + ir->pwled = 1; + return 0; } @@ -146,143 +166,124 @@ static void tm6000_ir_urb_received(struct urb *urb) { struct tm6000_core *dev = urb->context; struct tm6000_IR *ir = dev->ir; + struct tm6000_ir_poll_result poll_result; + char *buf; int rc; - if (urb->status != 0) - printk(KERN_INFO "not ready\n"); - else if (urb->actual_length > 0) { - memcpy(ir->urb_data, urb->transfer_buffer, urb->actual_length); + dprintk(2, "%s\n",__func__); + if (urb->status < 0 || urb->actual_length <= 0) { + printk(KERN_INFO "tm6000: IR URB failure: status: %i, length %i\n", + urb->status, urb->actual_length); + ir->submit_urb = 1; + schedule_delayed_work(&ir->work, msecs_to_jiffies(URB_SUBMIT_DELAY)); + return; + } + buf = urb->transfer_buffer; - dprintk("data %02x %02x %02x %02x\n", ir->urb_data[0], - ir->urb_data[1], ir->urb_data[2], ir->urb_data[3]); + if (ir_debug) + print_hex_dump(KERN_DEBUG, "tm6000: IR data: ", + DUMP_PREFIX_OFFSET,16, 1, + buf, urb->actual_length, false); - ir->key = 1; - } + poll_result.rc_data = buf[0]; + if (urb->actual_length > 1) + poll_result.rc_data |= buf[1] << 8; + + dprintk(1, "%s, scancode: 0x%04x\n",__func__, poll_result.rc_data); + rc_keydown(ir->rc, poll_result.rc_data, 0); rc = usb_submit_urb(urb, GFP_ATOMIC); + /* + * Flash the led. We can't do it here, as it is running on IRQ context. + * So, use the scheduler to do it, in a few ms. + */ + ir->pwled = 2; + schedule_delayed_work(&ir->work, msecs_to_jiffies(10)); } -static int default_polling_getkey(struct tm6000_IR *ir, - struct tm6000_ir_poll_result *poll_result) +static void tm6000_ir_handle_key(struct work_struct *work) { + struct tm6000_IR *ir = container_of(work, struct tm6000_IR, work.work); struct tm6000_core *dev = ir->dev; + struct tm6000_ir_poll_result poll_result; int rc; u8 buf[2]; - if (ir->wait && !&dev->int_in) - return 0; - - if (&dev->int_in) { - switch (ir->rc_type) { - case RC_TYPE_RC5: - poll_result->rc_data = ir->urb_data[0]; - break; - case RC_TYPE_NEC: - switch (dev->model) { - case 10: - case 11: - case 14: - case 15: - if (ir->urb_data[1] == - ((ir->key_addr >> 8) & 0xff)) { - poll_result->rc_data = - ir->urb_data[0] - | ir->urb_data[1] << 8; - } - break; - default: - poll_result->rc_data = ir->urb_data[0] - | ir->urb_data[1] << 8; - } - break; - default: - poll_result->rc_data = ir->urb_data[0] - | ir->urb_data[1] << 8; - break; - } - } else { - tm6000_set_reg(dev, REQ_04_EN_DISABLE_MCU_INT, 2, 0); - msleep(10); - tm6000_set_reg(dev, REQ_04_EN_DISABLE_MCU_INT, 2, 1); - msleep(10); - - if (ir->rc_type == RC_TYPE_RC5) { - rc = tm6000_read_write_usb(dev, USB_DIR_IN | - USB_TYPE_VENDOR | USB_RECIP_DEVICE, - REQ_02_GET_IR_CODE, 0, 0, buf, 1); - - msleep(10); - - dprintk("read data=%02x\n", buf[0]); - if (rc < 0) - return rc; + if (ir->wait) + return; - poll_result->rc_data = buf[0]; - } else { - rc = tm6000_read_write_usb(dev, USB_DIR_IN | - USB_TYPE_VENDOR | USB_RECIP_DEVICE, - REQ_02_GET_IR_CODE, 0, 0, buf, 2); + dprintk(3, "%s\n",__func__); - msleep(10); + rc = tm6000_read_write_usb(dev, USB_DIR_IN | + USB_TYPE_VENDOR | USB_RECIP_DEVICE, + REQ_02_GET_IR_CODE, 0, 0, buf, 2); + if (rc < 0) + return; - dprintk("read data=%04x\n", buf[0] | buf[1] << 8); - if (rc < 0) - return rc; + if (rc > 1) + poll_result.rc_data = buf[0] | buf[1] << 8; + else + poll_result.rc_data = buf[0]; - poll_result->rc_data = buf[0] | buf[1] << 8; + /* Check if something was read */ + if ((poll_result.rc_data & 0xff) == 0xff) { + if (!ir->pwled) { + tm6000_flash_led(dev, 1); + ir->pwled = 1; } - if ((poll_result->rc_data & 0x00ff) != 0xff) - ir->key = 1; + return; } - return 0; + + dprintk(1, "%s, scancode: 0x%04x\n",__func__, poll_result.rc_data); + rc_keydown(ir->rc, poll_result.rc_data, 0); + tm6000_flash_led(dev, 0); + ir->pwled = 0; + + /* Re-schedule polling */ + schedule_delayed_work(&ir->work, msecs_to_jiffies(ir->polling)); } -static void tm6000_ir_handle_key(struct tm6000_IR *ir) +static void tm6000_ir_int_work(struct work_struct *work) { + struct tm6000_IR *ir = container_of(work, struct tm6000_IR, work.work); struct tm6000_core *dev = ir->dev; - int result; - struct tm6000_ir_poll_result poll_result; + int rc; - /* read the registers containing the IR status */ - result = ir->get_key(ir, &poll_result); - if (result < 0) { - printk(KERN_INFO "ir->get_key() failed %d\n", result); - return; - } + dprintk(3, "%s, submit_urb = %d, pwled = %d\n",__func__, ir->submit_urb, + ir->pwled); - if (ir->pwled) { - if (ir->pwledcnt >= PWLED_OFF) { - ir->pwled = 0; - ir->pwledcnt = 0; - tm6000_flash_led(dev, 1); - } else - ir->pwledcnt += 1; + if (ir->submit_urb) { + dprintk(3, "Resubmit urb\n"); + tm6000_set_reg(dev, REQ_04_EN_DISABLE_MCU_INT, 2, 0); + + rc = usb_submit_urb(ir->int_urb, GFP_ATOMIC); + if (rc < 0) { + printk(KERN_ERR "tm6000: Can't submit an IR interrupt. Error %i\n", + rc); + /* Retry in 100 ms */ + schedule_delayed_work(&ir->work, msecs_to_jiffies(URB_SUBMIT_DELAY)); + return; + } + ir->submit_urb = 0; } - if (ir->key) { - dprintk("ir->get_key result data=%04x\n", poll_result.rc_data); - rc_keydown(ir->rc, poll_result.rc_data, 0); - ir->key = 0; - ir->pwled = 1; - ir->pwledcnt = 0; + /* Led is enabled only if USB submit doesn't fail */ + if (ir->pwled == 2) { tm6000_flash_led(dev, 0); + ir->pwled = 0; + schedule_delayed_work(&ir->work, msecs_to_jiffies(URB_INT_LED_DELAY)); + } else if (!ir->pwled) { + tm6000_flash_led(dev, 1); + ir->pwled = 1; } - return; -} - -static void tm6000_ir_work(struct work_struct *work) -{ - struct tm6000_IR *ir = container_of(work, struct tm6000_IR, work.work); - - tm6000_ir_handle_key(ir); - schedule_delayed_work(&ir->work, msecs_to_jiffies(ir->polling)); } static int tm6000_ir_start(struct rc_dev *rc) { struct tm6000_IR *ir = rc->priv; - INIT_DELAYED_WORK(&ir->work, tm6000_ir_work); + dprintk(2, "%s\n",__func__); + schedule_delayed_work(&ir->work, 0); return 0; @@ -292,6 +293,8 @@ static void tm6000_ir_stop(struct rc_dev *rc) { struct tm6000_IR *ir = rc->priv; + dprintk(2, "%s\n",__func__); + cancel_delayed_work_sync(&ir->work); } @@ -302,10 +305,11 @@ static int tm6000_ir_change_protocol(struct rc_dev *rc, u64 rc_type) if (!ir) return 0; + dprintk(2, "%s\n",__func__); + if ((rc->rc_map.scan) && (rc_type == RC_TYPE_NEC)) ir->key_addr = ((rc->rc_map.scan[0].scancode >> 8) & 0xffff); - ir->get_key = default_polling_getkey; ir->rc_type = rc_type; tm6000_ir_config(ir); @@ -313,17 +317,19 @@ static int tm6000_ir_change_protocol(struct rc_dev *rc, u64 rc_type) return 0; } -int tm6000_ir_int_start(struct tm6000_core *dev) +static int __tm6000_ir_int_start(struct rc_dev *rc) { - struct tm6000_IR *ir = dev->ir; + struct tm6000_IR *ir = rc->priv; + struct tm6000_core *dev = ir->dev; int pipe, size; int err = -ENOMEM; - if (!ir) return -ENODEV; - ir->int_urb = usb_alloc_urb(0, GFP_KERNEL); + dprintk(2, "%s\n",__func__); + + ir->int_urb = usb_alloc_urb(0, GFP_ATOMIC); if (!ir->int_urb) return -ENOMEM; @@ -332,42 +338,53 @@ int tm6000_ir_int_start(struct tm6000_core *dev) & USB_ENDPOINT_NUMBER_MASK); size = usb_maxpacket(dev->udev, pipe, usb_pipeout(pipe)); - dprintk("IR max size: %d\n", size); + dprintk(1, "IR max size: %d\n", size); - ir->int_urb->transfer_buffer = kzalloc(size, GFP_KERNEL); + ir->int_urb->transfer_buffer = kzalloc(size, GFP_ATOMIC); if (ir->int_urb->transfer_buffer == NULL) { usb_free_urb(ir->int_urb); return err; } - dprintk("int interval: %d\n", dev->int_in.endp->desc.bInterval); + dprintk(1, "int interval: %d\n", dev->int_in.endp->desc.bInterval); + usb_fill_int_urb(ir->int_urb, dev->udev, pipe, ir->int_urb->transfer_buffer, size, tm6000_ir_urb_received, dev, dev->int_in.endp->desc.bInterval); - err = usb_submit_urb(ir->int_urb, GFP_ATOMIC); - if (err) { - kfree(ir->int_urb->transfer_buffer); - usb_free_urb(ir->int_urb); - return err; - } - ir->urb_data = kzalloc(size, GFP_KERNEL); + + ir->submit_urb = 1; + schedule_delayed_work(&ir->work, msecs_to_jiffies(URB_SUBMIT_DELAY)); return 0; } -void tm6000_ir_int_stop(struct tm6000_core *dev) +static void __tm6000_ir_int_stop(struct rc_dev *rc) { - struct tm6000_IR *ir = dev->ir; + struct tm6000_IR *ir = rc->priv; - if (!ir) + if (!ir || !ir->int_urb) return; + dprintk(2, "%s\n",__func__); + usb_kill_urb(ir->int_urb); kfree(ir->int_urb->transfer_buffer); usb_free_urb(ir->int_urb); ir->int_urb = NULL; - kfree(ir->urb_data); - ir->urb_data = NULL; +} + +int tm6000_ir_int_start(struct tm6000_core *dev) +{ + struct tm6000_IR *ir = dev->ir; + + return __tm6000_ir_int_start(ir->rc); +} + +void tm6000_ir_int_stop(struct tm6000_core *dev) +{ + struct tm6000_IR *ir = dev->ir; + + __tm6000_ir_int_stop(ir->rc); } int tm6000_ir_init(struct tm6000_core *dev) @@ -385,7 +402,9 @@ int tm6000_ir_init(struct tm6000_core *dev) if (!dev->ir_codes) return 0; - ir = kzalloc(sizeof(*ir), GFP_KERNEL); + dprintk(2, "%s\n",__func__); + + ir = kzalloc(sizeof(*ir), GFP_ATOMIC); rc = rc_allocate_device(); if (!ir || !rc) goto out; @@ -395,19 +414,22 @@ int tm6000_ir_init(struct tm6000_core *dev) dev->ir = ir; ir->rc = rc; - /* input einrichten */ + /* input setup */ rc->allowed_protos = RC_TYPE_RC5 | RC_TYPE_NEC; rc->priv = ir; rc->change_protocol = tm6000_ir_change_protocol; - rc->open = tm6000_ir_start; - rc->close = tm6000_ir_stop; + if (&dev->int_in) { + rc->open = __tm6000_ir_int_start; + rc->close = __tm6000_ir_int_stop; + INIT_DELAYED_WORK(&ir->work, tm6000_ir_int_work); + } else { + rc->open = tm6000_ir_start; + rc->close = tm6000_ir_stop; + ir->polling = 50; + INIT_DELAYED_WORK(&ir->work, tm6000_ir_handle_key); + } rc->driver_type = RC_DRIVER_SCANCODE; - ir->polling = 50; - ir->pwled = 0; - ir->pwledcnt = 0; - - snprintf(ir->name, sizeof(ir->name), "tm5600/60x0 IR (%s)", dev->name); @@ -426,15 +448,6 @@ int tm6000_ir_init(struct tm6000_core *dev) rc->driver_name = "tm6000"; rc->dev.parent = &dev->udev->dev; - if (&dev->int_in) { - dprintk("IR over int\n"); - - err = tm6000_ir_int_start(dev); - - if (err) - goto out; - } - /* ir register */ err = rc_register_device(rc); if (err) @@ -458,10 +471,19 @@ int tm6000_ir_fini(struct tm6000_core *dev) if (!ir) return 0; + dprintk(2, "%s\n",__func__); + rc_unregister_device(ir->rc); - if (ir->int_urb) - tm6000_ir_int_stop(dev); + if (!ir->polling) + __tm6000_ir_int_stop(ir->rc); + + tm6000_ir_stop(ir->rc); + + /* Turn off the led */ + tm6000_flash_led(dev, 0); + ir->pwled = 0; + kfree(ir); dev->ir = NULL; -- cgit v0.10.2 From 8afc539c4a3df5da4e90c36cf21e2bc7a2572149 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 30 Nov 2011 13:26:10 -0300 Subject: [media] tm6000: Allow auto-detecting tm6000 devices Now that the tm6000 driver is on a good shape, we can enable device autodetection, based on the USB ID. Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/tm6000/tm6000-cards.c b/drivers/media/video/tm6000/tm6000-cards.c index 0b54132..3873ce4 100644 --- a/drivers/media/video/tm6000/tm6000-cards.c +++ b/drivers/media/video/tm6000/tm6000-cards.c @@ -640,6 +640,7 @@ static struct usb_device_id tm6000_id_table[] = { { USB_DEVICE(0x6000, 0xdec3), .driver_info = TM6010_BOARD_BEHOLD_VOYAGER_LITE }, { } }; +MODULE_DEVICE_TABLE(usb, tm6000_id_table); /* Control power led for show some activity */ void tm6000_flash_led(struct tm6000_core *dev, u8 state) -- cgit v0.10.2 From 9f711a80c5d0048e85c129f23281d9c0634e7010 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 30 Nov 2011 14:55:28 -0200 Subject: [media] tm6000: Use a 16 scancode bitmask for IR This should allow using 24 or 32 bits NEC IR decoding tables with those devices. Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/tm6000/tm6000-input.c b/drivers/media/video/tm6000/tm6000-input.c index 6eaf770..e3467d4 100644 --- a/drivers/media/video/tm6000/tm6000-input.c +++ b/drivers/media/video/tm6000/tm6000-input.c @@ -416,6 +416,8 @@ int tm6000_ir_init(struct tm6000_core *dev) /* input setup */ rc->allowed_protos = RC_TYPE_RC5 | RC_TYPE_NEC; + /* Neded, in order to support NEC remotes with 24 or 32 bits */ + rc->scanmask = 0xffff; rc->priv = ir; rc->change_protocol = tm6000_ir_change_protocol; if (&dev->int_in) { -- cgit v0.10.2 From 6740a932882f43056b8545e5b0b85511975d0a7c Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 30 Nov 2011 14:54:05 -0300 Subject: [media] tm6000: automatically load alsa and dvb modules All devices should support alsa module. Devices with DVB will auto-load the dvb module. This way, tm6000-based devices should now have hot plugin. Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/tm6000/tm6000-cards.c b/drivers/media/video/tm6000/tm6000-cards.c index 3873ce4..6b74259 100644 --- a/drivers/media/video/tm6000/tm6000-cards.c +++ b/drivers/media/video/tm6000/tm6000-cards.c @@ -1052,6 +1052,33 @@ static void use_alternative_detection_method(struct tm6000_core *dev) tm6000_boards[model].name, model); } +#if defined(CONFIG_MODULES) && defined(MODULE) +static void request_module_async(struct work_struct *work) +{ + struct tm6000_core *dev = container_of(work, struct tm6000_core, + request_module_wk); + + request_module("tm6000-alsa"); + + if (dev->caps.has_dvb) + request_module("tm6000-dvb"); +} + +static void request_modules(struct tm6000_core *dev) +{ + INIT_WORK(&dev->request_module_wk, request_module_async); + schedule_work(&dev->request_module_wk); +} + +static void flush_request_modules(struct tm6000_core *dev) +{ + flush_work_sync(&dev->request_module_wk); +} +#else +#define request_modules(dev) +#define flush_request_modules(dev) +#endif /* CONFIG_MODULES */ + static int tm6000_init_dev(struct tm6000_core *dev) { struct v4l2_frequency f; @@ -1114,6 +1141,8 @@ static int tm6000_init_dev(struct tm6000_core *dev) tm6000_ir_init(dev); + request_modules(dev); + mutex_unlock(&dev->lock); return 0; @@ -1326,6 +1355,8 @@ static void tm6000_usb_disconnect(struct usb_interface *interface) printk(KERN_INFO "tm6000: disconnecting %s\n", dev->name); + flush_request_modules(dev); + tm6000_ir_fini(dev); if (dev->gpio.power_led) { diff --git a/drivers/media/video/tm6000/tm6000.h b/drivers/media/video/tm6000/tm6000.h index 2777e51..27ba659 100644 --- a/drivers/media/video/tm6000/tm6000.h +++ b/drivers/media/video/tm6000/tm6000.h @@ -188,6 +188,9 @@ struct tm6000_core { /* Device Capabilities*/ struct tm6000_capabilities caps; + /* Used to load alsa/dvb */ + struct work_struct request_module_wk; + /* Tuner configuration */ int tuner_type; /* type of the tuner */ int tuner_addr; /* tuner address */ -- cgit v0.10.2 From 2a887d27708a4f9f3b5ad8258f9e19a150b58f03 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 30 Nov 2011 14:57:28 -0300 Subject: [media] tm6000: fix OOPS at tm6000_ir_int_stop() and tm6000_ir_int_start() [ 3755.608233] BUG: unable to handle kernel NULL pointer dereference at 0000000000000008 [ 3755.616360] IP: [] tm6000_ir_int_stop+0x10/0x1b [tm6000] Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/tm6000/tm6000-input.c b/drivers/media/video/tm6000/tm6000-input.c index e3467d4..af4bcf5 100644 --- a/drivers/media/video/tm6000/tm6000-input.c +++ b/drivers/media/video/tm6000/tm6000-input.c @@ -377,6 +377,9 @@ int tm6000_ir_int_start(struct tm6000_core *dev) { struct tm6000_IR *ir = dev->ir; + if (!ir) + return; + return __tm6000_ir_int_start(ir->rc); } @@ -384,6 +387,9 @@ void tm6000_ir_int_stop(struct tm6000_core *dev) { struct tm6000_IR *ir = dev->ir; + if (!ir || !ir->rc) + return; + __tm6000_ir_int_stop(ir->rc); } -- cgit v0.10.2 From a47161a55e40203e5dae6d04df3b159551377365 Mon Sep 17 00:00:00 2001 From: Ilya Yanok Date: Sun, 20 Nov 2011 19:15:39 +0100 Subject: OMAPDSS: add FocalTech ETM070003DH6 display support Add data for the FocalTech ETM070003DH6 display to the generic_dpi_panel display driver. Signed-off-by: Ilya Yanok Signed-off-by: Tomi Valkeinen diff --git a/drivers/video/omap2/displays/panel-generic-dpi.c b/drivers/video/omap2/displays/panel-generic-dpi.c index 519c47d..593f831 100644 --- a/drivers/video/omap2/displays/panel-generic-dpi.c +++ b/drivers/video/omap2/displays/panel-generic-dpi.c @@ -297,6 +297,26 @@ static struct panel_config generic_dpi_panels[] = { .name = "apollon", }, + /* FocalTech ETM070003DH6 */ + { + { + .x_res = 800, + .y_res = 480, + + .pixel_clock = 28000, + + .hsw = 48, + .hfp = 40, + .hbp = 40, + + .vsw = 3, + .vfp = 13, + .vbp = 29, + }, + .config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS | + OMAP_DSS_LCD_IHS, + .name = "focaltech_etm070003dh6", + }, }; struct panel_drv_data { -- cgit v0.10.2 From a702c85906390282e2aabb6cb30e448e23ee1599 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Wed, 12 Oct 2011 10:10:21 +0300 Subject: OMAPDSS: DSI: flush posted write when entering ULPS Flush posted write between writing the ULPS enable bits and waiting for the interrupt. Signed-off-by: Tomi Valkeinen diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c index 5abf8e7..1331f92 100644 --- a/drivers/video/omap2/dss/dsi.c +++ b/drivers/video/omap2/dss/dsi.c @@ -3561,6 +3561,9 @@ static int dsi_enter_ulps(struct platform_device *dsidev) REG_FLD_MOD(dsidev, DSI_COMPLEXIO_CFG2, (1 << 0) | (1 << 1) | (1 << 2), 7, 5); + /* flush posted write and wait for SCP interface to finish the write */ + dsi_read_reg(dsidev, DSI_COMPLEXIO_CFG2); + if (wait_for_completion_timeout(&completion, msecs_to_jiffies(1000)) == 0) { DSSERR("ULPS enable timeout\n"); @@ -3575,6 +3578,9 @@ static int dsi_enter_ulps(struct platform_device *dsidev) REG_FLD_MOD(dsidev, DSI_COMPLEXIO_CFG2, (0 << 0) | (0 << 1) | (0 << 2), 7, 5); + /* flush posted write and wait for SCP interface to finish the write */ + dsi_read_reg(dsidev, DSI_COMPLEXIO_CFG2); + dsi_cio_power(dsidev, DSI_COMPLEXIO_POWER_ULPS); dsi_if_enable(dsidev, false); -- cgit v0.10.2 From 968f8e97a3291a3c7c9a2dee1a85a092de638f65 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Wed, 12 Oct 2011 10:13:14 +0300 Subject: OMAPDSS: DSI: flush posted write in send_bta Flush posted write after setting the bit to send the BTA to ensure the BTA is sent right away, as the code in dsi_vc_send_bta_sync() waits for an interrupt caused indirectly by sending the BTA. Signed-off-by: Tomi Valkeinen diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c index 1331f92..4b1c074 100644 --- a/drivers/video/omap2/dss/dsi.c +++ b/drivers/video/omap2/dss/dsi.c @@ -2913,6 +2913,9 @@ static int dsi_vc_send_bta(struct platform_device *dsidev, int channel) REG_FLD_MOD(dsidev, DSI_VC_CTRL(channel), 1, 6, 6); /* BTA_EN */ + /* flush posted write */ + dsi_read_reg(dsidev, DSI_VC_CTRL(channel)); + return 0; } -- cgit v0.10.2 From b6a44e7748527d01b0c2f9a67686babaf0a5e53b Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Wed, 12 Oct 2011 10:17:02 +0300 Subject: OMAPDSS: DISPC: Flush posted writes when enabling outputs Flush posted write in _enable_lcd_out() and _enable_digit_out(). This ensures the the lcd/digit bit is written before the code starts waiting for interrupts about enabling/disabling the output. Signed-off-by: Tomi Valkeinen diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c index 5c81533..5bbd838 100644 --- a/drivers/video/omap2/dss/dispc.c +++ b/drivers/video/omap2/dss/dispc.c @@ -1916,10 +1916,14 @@ static void dispc_disable_isr(void *data, u32 mask) static void _enable_lcd_out(enum omap_channel channel, bool enable) { - if (channel == OMAP_DSS_CHANNEL_LCD2) + if (channel == OMAP_DSS_CHANNEL_LCD2) { REG_FLD_MOD(DISPC_CONTROL2, enable ? 1 : 0, 0, 0); - else + /* flush posted write */ + dispc_read_reg(DISPC_CONTROL2); + } else { REG_FLD_MOD(DISPC_CONTROL, enable ? 1 : 0, 0, 0); + dispc_read_reg(DISPC_CONTROL); + } } static void dispc_mgr_enable_lcd_out(enum omap_channel channel, bool enable) @@ -1967,6 +1971,8 @@ static void dispc_mgr_enable_lcd_out(enum omap_channel channel, bool enable) static void _enable_digit_out(bool enable) { REG_FLD_MOD(DISPC_CONTROL, enable ? 1 : 0, 1, 1); + /* flush posted write */ + dispc_read_reg(DISPC_CONTROL); } static void dispc_mgr_enable_digit_out(bool enable) -- cgit v0.10.2 From d982085050e67da24a57ec04eb3701eb4805118a Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Wed, 12 Oct 2011 15:05:59 +0300 Subject: OMAPDSS: DSI: count with number of lanes DSI driver currently counts used lanes and number of supported lanes by using the number of data lanes (i.e. excluding clock lane). This patch changes this to use the number of all lanes so that the following lane config patches are cleaner. Signed-off-by: Tomi Valkeinen diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c index 4b1c074..6a110b2 100644 --- a/drivers/video/omap2/dss/dsi.c +++ b/drivers/video/omap2/dss/dsi.c @@ -327,7 +327,7 @@ struct dsi_data { unsigned long fint_min, fint_max; unsigned long lpdiv_max; - int num_data_lanes; + unsigned num_lanes_supported; unsigned scp_clk_refcount; }; @@ -2029,19 +2029,8 @@ static int dsi_cio_power(struct platform_device *dsidev, return 0; } -/* Number of data lanes present on DSI interface */ -static inline int dsi_get_num_data_lanes(struct platform_device *dsidev) -{ - /* DSI on OMAP3 doesn't have register DSI_GNQ, set number - * of data lanes as 2 by default */ - if (dss_has_feature(FEAT_DSI_GNQ)) - return REG_GET(dsidev, DSI_GNQ, 11, 9); /* NB_DATA_LANES */ - else - return 2; -} - -/* Number of data lanes used by the dss device */ -static inline int dsi_get_num_data_lanes_dssdev(struct omap_dss_device *dssdev) +/* Number of lanes used by the dss device */ +static inline int dsi_get_num_lanes_used(struct omap_dss_device *dssdev) { int num_data_lanes = 0; @@ -2054,7 +2043,7 @@ static inline int dsi_get_num_data_lanes_dssdev(struct omap_dss_device *dssdev) if (dssdev->phy.dsi.data4_lane != 0) num_data_lanes++; - return num_data_lanes; + return num_data_lanes + 1; } static unsigned dsi_get_line_buf_size(struct platform_device *dsidev) @@ -2092,7 +2081,7 @@ static void dsi_set_lane_config(struct omap_dss_device *dssdev) { struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); u32 r; - int num_data_lanes_dssdev = dsi_get_num_data_lanes_dssdev(dssdev); + int num_lanes_used = dsi_get_num_lanes_used(dssdev); int clk_lane = dssdev->phy.dsi.clk_lane; int data1_lane = dssdev->phy.dsi.data1_lane; @@ -2108,14 +2097,14 @@ static void dsi_set_lane_config(struct omap_dss_device *dssdev) r = FLD_MOD(r, data1_pol, 7, 7); r = FLD_MOD(r, data2_lane, 10, 8); r = FLD_MOD(r, data2_pol, 11, 11); - if (num_data_lanes_dssdev > 2) { + if (num_lanes_used > 3) { int data3_lane = dssdev->phy.dsi.data3_lane; int data3_pol = dssdev->phy.dsi.data3_pol; r = FLD_MOD(r, data3_lane, 14, 12); r = FLD_MOD(r, data3_pol, 15, 15); } - if (num_data_lanes_dssdev > 3) { + if (num_lanes_used > 4) { int data4_lane = dssdev->phy.dsi.data4_lane; int data4_pol = dssdev->phy.dsi.data4_pol; @@ -2247,7 +2236,7 @@ static void dsi_cio_enable_lane_override(struct omap_dss_device *dssdev, int data4_pol = dssdev->phy.dsi.data4_pol; u32 l = 0; - u8 lptxscp_start = dsi->num_data_lanes == 2 ? 22 : 26; + u8 lptxscp_start = dsi->num_lanes_supported == 3 ? 22 : 26; if (lanes & DSI_CLK_P) l |= 1 << ((clk_lane - 1) * 2 + (clk_pol ? 0 : 1)); @@ -2385,7 +2374,7 @@ static int dsi_cio_init(struct omap_dss_device *dssdev) struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); int r; - int num_data_lanes_dssdev = dsi_get_num_data_lanes_dssdev(dssdev); + int num_lanes_used = dsi_get_num_lanes_used(dssdev); u32 l; DSSDBGF(); @@ -2430,10 +2419,10 @@ static int dsi_cio_init(struct omap_dss_device *dssdev) * manually. */ - if (num_data_lanes_dssdev > 2) + if (num_lanes_used > 3) lane_mask |= DSI_DATA3_P; - if (num_data_lanes_dssdev > 3) + if (num_lanes_used > 4) lane_mask |= DSI_DATA4_P; dsi_cio_enable_lane_override(dssdev, lane_mask); @@ -3852,7 +3841,7 @@ static void dsi_proto_timings(struct omap_dss_device *dssdev) unsigned ddr_clk_pre, ddr_clk_post; unsigned enter_hs_mode_lat, exit_hs_mode_lat; unsigned ths_eot; - int ndl = dsi_get_num_data_lanes_dssdev(dssdev); + int ndl = dsi_get_num_lanes_used(dssdev) - 1; u32 r; r = dsi_read_reg(dsidev, DSI_DSIPHY_CFG0); @@ -4552,9 +4541,9 @@ int dsi_init_display(struct omap_dss_device *dssdev) dsi->vdds_dsi_reg = vdds_dsi; } - if (dsi_get_num_data_lanes_dssdev(dssdev) > dsi->num_data_lanes) { - DSSERR("DSI%d can't support more than %d data lanes\n", - dsi_module + 1, dsi->num_data_lanes); + if (dsi_get_num_lanes_used(dssdev) > dsi->num_lanes_supported) { + DSSERR("DSI%d can't support more than %d lanes\n", + dsi_module + 1, dsi->num_lanes_supported); return -EINVAL; } @@ -4780,7 +4769,13 @@ static int omap_dsihw_probe(struct platform_device *dsidev) dev_dbg(&dsidev->dev, "OMAP DSI rev %d.%d\n", FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0)); - dsi->num_data_lanes = dsi_get_num_data_lanes(dsidev); + /* DSI on OMAP3 doesn't have register DSI_GNQ, set number + * of data to 3 by default */ + if (dss_has_feature(FEAT_DSI_GNQ)) + /* NB_DATA_LANES */ + dsi->num_lanes_supported = 1 + REG_GET(dsidev, DSI_GNQ, 11, 9); + else + dsi->num_lanes_supported = 3; dsi_runtime_put(dsidev); -- cgit v0.10.2 From 739a7f46cbf6dc3d4f899e4b566196d99403457a Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Thu, 13 Oct 2011 11:22:06 +0300 Subject: OMAPDSS: DSI: Parse lane config Parse the lane configuration from the device data into internal lane config format. This will be used in the following patches to clean up the lane handling. Signed-off-by: Tomi Valkeinen diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c index 6a110b2..aea110c 100644 --- a/drivers/video/omap2/dss/dsi.c +++ b/drivers/video/omap2/dss/dsi.c @@ -203,6 +203,21 @@ struct dsi_reg { u16 idx; }; typedef void (*omap_dsi_isr_t) (void *arg, u32 mask); #define DSI_MAX_NR_ISRS 2 +#define DSI_MAX_NR_LANES 5 + +enum dsi_lane_function { + DSI_LANE_UNUSED = 0, + DSI_LANE_CLK, + DSI_LANE_DATA1, + DSI_LANE_DATA2, + DSI_LANE_DATA3, + DSI_LANE_DATA4, +}; + +struct dsi_lane_config { + enum dsi_lane_function function; + u8 polarity; +}; struct dsi_isr_data { omap_dsi_isr_t isr; @@ -329,6 +344,9 @@ struct dsi_data { unsigned num_lanes_supported; + struct dsi_lane_config lanes[DSI_MAX_NR_LANES]; + unsigned num_lanes_used; + unsigned scp_clk_refcount; }; @@ -2077,6 +2095,65 @@ static unsigned dsi_get_line_buf_size(struct platform_device *dsidev) } } +static int dsi_parse_lane_config(struct omap_dss_device *dssdev) +{ + struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); + struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); + u8 lanes[DSI_MAX_NR_LANES]; + u8 polarities[DSI_MAX_NR_LANES]; + int num_lanes, i; + + static const enum dsi_lane_function functions[] = { + DSI_LANE_CLK, + DSI_LANE_DATA1, + DSI_LANE_DATA2, + DSI_LANE_DATA3, + DSI_LANE_DATA4, + }; + + lanes[0] = dssdev->phy.dsi.clk_lane; + lanes[1] = dssdev->phy.dsi.data1_lane; + lanes[2] = dssdev->phy.dsi.data2_lane; + lanes[3] = dssdev->phy.dsi.data3_lane; + lanes[4] = dssdev->phy.dsi.data4_lane; + polarities[0] = dssdev->phy.dsi.clk_pol; + polarities[1] = dssdev->phy.dsi.data1_pol; + polarities[2] = dssdev->phy.dsi.data2_pol; + polarities[3] = dssdev->phy.dsi.data3_pol; + polarities[4] = dssdev->phy.dsi.data4_pol; + + num_lanes = 0; + + for (i = 0; i < dsi->num_lanes_supported; ++i) + dsi->lanes[i].function = DSI_LANE_UNUSED; + + for (i = 0; i < dsi->num_lanes_supported; ++i) { + int num; + + if (lanes[i] == DSI_LANE_UNUSED) + break; + + num = lanes[i] - 1; + + if (num >= dsi->num_lanes_supported) + return -EINVAL; + + if (dsi->lanes[num].function != DSI_LANE_UNUSED) + return -EINVAL; + + dsi->lanes[num].function = functions[i]; + dsi->lanes[num].polarity = polarities[i]; + num_lanes++; + } + + if (num_lanes < 2 || num_lanes > dsi->num_lanes_supported) + return -EINVAL; + + dsi->num_lanes_used = num_lanes; + + return 0; +} + static void dsi_set_lane_config(struct omap_dss_device *dssdev) { struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); @@ -4328,6 +4405,12 @@ static int dsi_display_init_dsi(struct omap_dss_device *dssdev) int dsi_module = dsi_get_dsidev_id(dsidev); int r; + r = dsi_parse_lane_config(dssdev); + if (r) { + DSSERR("illegal lane config"); + goto err0; + } + r = dsi_pll_init(dsidev, true, true); if (r) goto err0; -- cgit v0.10.2 From 48368395f670ac8cc60288674de940a38693412e Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Thu, 13 Oct 2011 11:22:39 +0300 Subject: OMAPDSS: DSI: Use new lane config in dsi_set_lane_config Use the new lane config in dsi_set_lane_config(). Signed-off-by: Tomi Valkeinen diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c index aea110c..ba8d6b3 100644 --- a/drivers/video/omap2/dss/dsi.c +++ b/drivers/video/omap2/dss/dsi.c @@ -2154,59 +2154,53 @@ static int dsi_parse_lane_config(struct omap_dss_device *dssdev) return 0; } -static void dsi_set_lane_config(struct omap_dss_device *dssdev) +static int dsi_set_lane_config(struct omap_dss_device *dssdev) { struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); + struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); + static const u8 offsets[] = { 0, 4, 8, 12, 16 }; + static const enum dsi_lane_function functions[] = { + DSI_LANE_CLK, + DSI_LANE_DATA1, + DSI_LANE_DATA2, + DSI_LANE_DATA3, + DSI_LANE_DATA4, + }; u32 r; - int num_lanes_used = dsi_get_num_lanes_used(dssdev); - - int clk_lane = dssdev->phy.dsi.clk_lane; - int data1_lane = dssdev->phy.dsi.data1_lane; - int data2_lane = dssdev->phy.dsi.data2_lane; - int clk_pol = dssdev->phy.dsi.clk_pol; - int data1_pol = dssdev->phy.dsi.data1_pol; - int data2_pol = dssdev->phy.dsi.data2_pol; + int i; r = dsi_read_reg(dsidev, DSI_COMPLEXIO_CFG1); - r = FLD_MOD(r, clk_lane, 2, 0); - r = FLD_MOD(r, clk_pol, 3, 3); - r = FLD_MOD(r, data1_lane, 6, 4); - r = FLD_MOD(r, data1_pol, 7, 7); - r = FLD_MOD(r, data2_lane, 10, 8); - r = FLD_MOD(r, data2_pol, 11, 11); - if (num_lanes_used > 3) { - int data3_lane = dssdev->phy.dsi.data3_lane; - int data3_pol = dssdev->phy.dsi.data3_pol; - - r = FLD_MOD(r, data3_lane, 14, 12); - r = FLD_MOD(r, data3_pol, 15, 15); + + for (i = 0; i < dsi->num_lanes_used; ++i) { + unsigned offset = offsets[i]; + unsigned polarity, lane_number; + unsigned t; + + for (t = 0; t < dsi->num_lanes_supported; ++t) + if (dsi->lanes[t].function == functions[i]) + break; + + if (t == dsi->num_lanes_supported) + return -EINVAL; + + lane_number = t; + polarity = dsi->lanes[t].polarity; + + r = FLD_MOD(r, lane_number + 1, offset + 2, offset); + r = FLD_MOD(r, polarity, offset + 3, offset + 3); } - if (num_lanes_used > 4) { - int data4_lane = dssdev->phy.dsi.data4_lane; - int data4_pol = dssdev->phy.dsi.data4_pol; - r = FLD_MOD(r, data4_lane, 18, 16); - r = FLD_MOD(r, data4_pol, 19, 19); + /* clear the unused lanes */ + for (; i < dsi->num_lanes_supported; ++i) { + unsigned offset = offsets[i]; + + r = FLD_MOD(r, 0, offset + 2, offset); + r = FLD_MOD(r, 0, offset + 3, offset + 3); } - dsi_write_reg(dsidev, DSI_COMPLEXIO_CFG1, r); - /* The configuration of the DSI complex I/O (number of data lanes, - position, differential order) should not be changed while - DSS.DSI_CLK_CRTRL[20] LP_CLK_ENABLE bit is set to 1. In order for - the hardware to take into account a new configuration of the complex - I/O (done in DSS.DSI_COMPLEXIO_CFG1 register), it is recommended to - follow this sequence: First set the DSS.DSI_CTRL[0] IF_EN bit to 1, - then reset the DSS.DSI_CTRL[0] IF_EN to 0, then set - DSS.DSI_CLK_CTRL[20] LP_CLK_ENABLE to 1 and finally set again the - DSS.DSI_CTRL[0] IF_EN bit to 1. If the sequence is not followed, the - DSI complex I/O configuration is unknown. */ + dsi_write_reg(dsidev, DSI_COMPLEXIO_CFG1, r); - /* - REG_FLD_MOD(dsidev, DSI_CTRL, 1, 0, 0); - REG_FLD_MOD(dsidev, DSI_CTRL, 0, 0, 0); - REG_FLD_MOD(dsidev, DSI_CLK_CTRL, 1, 20, 20); - REG_FLD_MOD(dsidev, DSI_CTRL, 1, 0, 0); - */ + return 0; } static inline unsigned ns2ddr(struct platform_device *dsidev, unsigned ns) @@ -2473,7 +2467,9 @@ static int dsi_cio_init(struct omap_dss_device *dssdev) goto err_scp_clk_dom; } - dsi_set_lane_config(dssdev); + r = dsi_set_lane_config(dssdev); + if (r) + goto err_scp_clk_dom; /* set TX STOP MODE timer to maximum for this operation */ l = dsi_read_reg(dsidev, DSI_TIMING1); -- cgit v0.10.2 From 85f17e8e2c8d5f9266ca28f05cbc57598eddb05a Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Thu, 13 Oct 2011 15:12:23 +0300 Subject: OMAPDSS: DSI: use lane config in dsi_get_lane_mask Use the new lane config in dsi_get_lane_mask(). Signed-off-by: Tomi Valkeinen diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c index ba8d6b3..1a209a2 100644 --- a/drivers/video/omap2/dss/dsi.c +++ b/drivers/video/omap2/dss/dsi.c @@ -2422,22 +2422,20 @@ static int dsi_cio_wait_tx_clk_esc_reset(struct omap_dss_device *dssdev) return 0; } +/* return bitmask of enabled lanes, lane0 being the lsb */ static unsigned dsi_get_lane_mask(struct omap_dss_device *dssdev) { - unsigned lanes = 0; + struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); + struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); + unsigned mask = 0; + int i; - if (dssdev->phy.dsi.clk_lane != 0) - lanes |= 1 << (dssdev->phy.dsi.clk_lane - 1); - if (dssdev->phy.dsi.data1_lane != 0) - lanes |= 1 << (dssdev->phy.dsi.data1_lane - 1); - if (dssdev->phy.dsi.data2_lane != 0) - lanes |= 1 << (dssdev->phy.dsi.data2_lane - 1); - if (dssdev->phy.dsi.data3_lane != 0) - lanes |= 1 << (dssdev->phy.dsi.data3_lane - 1); - if (dssdev->phy.dsi.data4_lane != 0) - lanes |= 1 << (dssdev->phy.dsi.data4_lane - 1); + for (i = 0; i < dsi->num_lanes_supported; ++i) { + if (dsi->lanes[i].function != DSI_LANE_UNUSED) + mask |= 1 << i; + } - return lanes; + return mask; } static int dsi_cio_init(struct omap_dss_device *dssdev) -- cgit v0.10.2 From 8dc0766fcf3b84ec83aa601acabf21f2c98ca253 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Thu, 13 Oct 2011 15:26:50 +0300 Subject: OMAPDSS: DSI: use lane config in dsi_cio_wait_tx_clk_esc_reset Use the new lane config in dsi_cio_wait_tx_clk_esc_reset(). This also extends the function to support 5 lanes on OMAP4, instead of 3 lanes. Signed-off-by: Tomi Valkeinen diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c index 1a209a2..52cf97f 100644 --- a/drivers/video/omap2/dss/dsi.c +++ b/drivers/video/omap2/dss/dsi.c @@ -2365,51 +2365,40 @@ static void dsi_cio_disable_lane_override(struct platform_device *dsidev) static int dsi_cio_wait_tx_clk_esc_reset(struct omap_dss_device *dssdev) { struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); - int t; - int bits[3]; - bool in_use[3]; - - if (dss_has_feature(FEAT_DSI_REVERSE_TXCLKESC)) { - bits[0] = 28; - bits[1] = 27; - bits[2] = 26; - } else { - bits[0] = 24; - bits[1] = 25; - bits[2] = 26; - } - - in_use[0] = false; - in_use[1] = false; - in_use[2] = false; + struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); + int t, i; + bool in_use[DSI_MAX_NR_LANES]; + static const u8 offsets_old[] = { 28, 27, 26 }; + static const u8 offsets_new[] = { 24, 25, 26, 27, 28 }; + const u8 *offsets; + + if (dss_has_feature(FEAT_DSI_REVERSE_TXCLKESC)) + offsets = offsets_old; + else + offsets = offsets_new; - if (dssdev->phy.dsi.clk_lane != 0) - in_use[dssdev->phy.dsi.clk_lane - 1] = true; - if (dssdev->phy.dsi.data1_lane != 0) - in_use[dssdev->phy.dsi.data1_lane - 1] = true; - if (dssdev->phy.dsi.data2_lane != 0) - in_use[dssdev->phy.dsi.data2_lane - 1] = true; + for (i = 0; i < dsi->num_lanes_supported; ++i) + in_use[i] = dsi->lanes[i].function != DSI_LANE_UNUSED; t = 100000; while (true) { u32 l; - int i; int ok; l = dsi_read_reg(dsidev, DSI_DSIPHY_CFG5); ok = 0; - for (i = 0; i < 3; ++i) { - if (!in_use[i] || (l & (1 << bits[i]))) + for (i = 0; i < dsi->num_lanes_supported; ++i) { + if (!in_use[i] || (l & (1 << offsets[i]))) ok++; } - if (ok == 3) + if (ok == dsi->num_lanes_supported) break; if (--t == 0) { - for (i = 0; i < 3; ++i) { - if (!in_use[i] || (l & (1 << bits[i]))) + for (i = 0; i < dsi->num_lanes_supported; ++i) { + if (!in_use[i] || (l & (1 << offsets[i]))) continue; DSSERR("CIO TXCLKESC%d domain not coming " \ -- cgit v0.10.2 From 9b4362f2b5ad6d0cf6b5754000b8db80d0592e89 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Thu, 13 Oct 2011 16:06:43 +0300 Subject: OMAPDSS: DSI: use lane config in dsi_cio_enable_lane_override Use the new lane config in dsi_cio_enable_lane_override(). The function parameters are also slightly changed. Signed-off-by: Tomi Valkeinen diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c index 52cf97f..dee9525 100644 --- a/drivers/video/omap2/dss/dsi.c +++ b/drivers/video/omap2/dss/dsi.c @@ -238,19 +238,6 @@ enum dsi_vc_source { DSI_VC_SOURCE_VP, }; -enum dsi_lane { - DSI_CLK_P = 1 << 0, - DSI_CLK_N = 1 << 1, - DSI_DATA1_P = 1 << 2, - DSI_DATA1_N = 1 << 3, - DSI_DATA2_P = 1 << 4, - DSI_DATA2_N = 1 << 5, - DSI_DATA3_P = 1 << 6, - DSI_DATA3_N = 1 << 7, - DSI_DATA4_P = 1 << 8, - DSI_DATA4_N = 1 << 9, -}; - struct dsi_update_region { u16 x, y, w, h; struct omap_dss_device *device; @@ -2290,49 +2277,28 @@ static void dsi_cio_timings(struct platform_device *dsidev) dsi_write_reg(dsidev, DSI_DSIPHY_CFG2, r); } +/* lane masks have lane 0 at lsb. mask_p for positive lines, n for negative */ static void dsi_cio_enable_lane_override(struct omap_dss_device *dssdev, - enum dsi_lane lanes) + unsigned mask_p, unsigned mask_n) { struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); - int clk_lane = dssdev->phy.dsi.clk_lane; - int data1_lane = dssdev->phy.dsi.data1_lane; - int data2_lane = dssdev->phy.dsi.data2_lane; - int data3_lane = dssdev->phy.dsi.data3_lane; - int data4_lane = dssdev->phy.dsi.data4_lane; - int clk_pol = dssdev->phy.dsi.clk_pol; - int data1_pol = dssdev->phy.dsi.data1_pol; - int data2_pol = dssdev->phy.dsi.data2_pol; - int data3_pol = dssdev->phy.dsi.data3_pol; - int data4_pol = dssdev->phy.dsi.data4_pol; - - u32 l = 0; + int i; + u32 l; u8 lptxscp_start = dsi->num_lanes_supported == 3 ? 22 : 26; - if (lanes & DSI_CLK_P) - l |= 1 << ((clk_lane - 1) * 2 + (clk_pol ? 0 : 1)); - if (lanes & DSI_CLK_N) - l |= 1 << ((clk_lane - 1) * 2 + (clk_pol ? 1 : 0)); - - if (lanes & DSI_DATA1_P) - l |= 1 << ((data1_lane - 1) * 2 + (data1_pol ? 0 : 1)); - if (lanes & DSI_DATA1_N) - l |= 1 << ((data1_lane - 1) * 2 + (data1_pol ? 1 : 0)); - - if (lanes & DSI_DATA2_P) - l |= 1 << ((data2_lane - 1) * 2 + (data2_pol ? 0 : 1)); - if (lanes & DSI_DATA2_N) - l |= 1 << ((data2_lane - 1) * 2 + (data2_pol ? 1 : 0)); - - if (lanes & DSI_DATA3_P) - l |= 1 << ((data3_lane - 1) * 2 + (data3_pol ? 0 : 1)); - if (lanes & DSI_DATA3_N) - l |= 1 << ((data3_lane - 1) * 2 + (data3_pol ? 1 : 0)); - - if (lanes & DSI_DATA4_P) - l |= 1 << ((data4_lane - 1) * 2 + (data4_pol ? 0 : 1)); - if (lanes & DSI_DATA4_N) - l |= 1 << ((data4_lane - 1) * 2 + (data4_pol ? 1 : 0)); + l = 0; + + for (i = 0; i < dsi->num_lanes_supported; ++i) { + unsigned p = dsi->lanes[i].polarity; + + if (mask_p & (1 << i)) + l |= 1 << (i * 2 + (p ? 0 : 1)); + + if (mask_n & (1 << i)) + l |= 1 << (i * 2 + (p ? 1 : 0)); + } + /* * Bits in REGLPTXSCPDAT4TO0DXDY: * 17: DY0 18: DX0 @@ -2432,7 +2398,6 @@ static int dsi_cio_init(struct omap_dss_device *dssdev) struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); int r; - int num_lanes_used = dsi_get_num_lanes_used(dssdev); u32 l; DSSDBGF(); @@ -2467,7 +2432,8 @@ static int dsi_cio_init(struct omap_dss_device *dssdev) dsi_write_reg(dsidev, DSI_TIMING1, l); if (dsi->ulps_enabled) { - u32 lane_mask = DSI_CLK_P | DSI_DATA1_P | DSI_DATA2_P; + unsigned mask_p; + int i; DSSDBG("manual ulps exit\n"); @@ -2476,16 +2442,19 @@ static int dsi_cio_init(struct omap_dss_device *dssdev) * ULPS exit sequence, as after reset the DSS HW thinks * that we are not in ULPS mode, and refuses to send the * sequence. So we need to send the ULPS exit sequence - * manually. + * manually by setting positive lines high and negative lines + * low for 1ms. */ - if (num_lanes_used > 3) - lane_mask |= DSI_DATA3_P; + mask_p = 0; - if (num_lanes_used > 4) - lane_mask |= DSI_DATA4_P; + for (i = 0; i < dsi->num_lanes_supported; ++i) { + if (dsi->lanes[i].function == DSI_LANE_UNUSED) + continue; + mask_p |= 1 << i; + } - dsi_cio_enable_lane_override(dssdev, lane_mask); + dsi_cio_enable_lane_override(dssdev, mask_p, 0); } r = dsi_cio_power(dsidev, DSI_COMPLEXIO_POWER_ON); -- cgit v0.10.2 From db18644f90e664bf30f58cf9b8bc879598bff62f Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Thu, 13 Oct 2011 16:12:29 +0300 Subject: OMAPDSS: DSI: remove dsi_get_num_lanes_used There's no longer need for the dsi_get_num_lanes_used function, so it can be removed. The lane check in dsi_init_display() can be removed as the validity of the config will be verified when parsing it. Signed-off-by: Tomi Valkeinen diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c index dee9525..2b375c6 100644 --- a/drivers/video/omap2/dss/dsi.c +++ b/drivers/video/omap2/dss/dsi.c @@ -2034,23 +2034,6 @@ static int dsi_cio_power(struct platform_device *dsidev, return 0; } -/* Number of lanes used by the dss device */ -static inline int dsi_get_num_lanes_used(struct omap_dss_device *dssdev) -{ - int num_data_lanes = 0; - - if (dssdev->phy.dsi.data1_lane != 0) - num_data_lanes++; - if (dssdev->phy.dsi.data2_lane != 0) - num_data_lanes++; - if (dssdev->phy.dsi.data3_lane != 0) - num_data_lanes++; - if (dssdev->phy.dsi.data4_lane != 0) - num_data_lanes++; - - return num_data_lanes + 1; -} - static unsigned dsi_get_line_buf_size(struct platform_device *dsidev) { int val; @@ -3863,6 +3846,7 @@ static int dsi_proto_config(struct omap_dss_device *dssdev) static void dsi_proto_timings(struct omap_dss_device *dssdev) { struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); + struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); unsigned tlpx, tclk_zero, tclk_prepare, tclk_trail; unsigned tclk_pre, tclk_post; unsigned ths_prepare, ths_prepare_ths_zero, ths_zero; @@ -3870,7 +3854,7 @@ static void dsi_proto_timings(struct omap_dss_device *dssdev) unsigned ddr_clk_pre, ddr_clk_post; unsigned enter_hs_mode_lat, exit_hs_mode_lat; unsigned ths_eot; - int ndl = dsi_get_num_lanes_used(dssdev) - 1; + int ndl = dsi->num_lanes_used - 1; u32 r; r = dsi_read_reg(dsidev, DSI_DSIPHY_CFG0); @@ -4554,7 +4538,6 @@ int dsi_init_display(struct omap_dss_device *dssdev) { struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); - int dsi_module = dsi_get_dsidev_id(dsidev); DSSDBG("DSI init\n"); @@ -4576,12 +4559,6 @@ int dsi_init_display(struct omap_dss_device *dssdev) dsi->vdds_dsi_reg = vdds_dsi; } - if (dsi_get_num_lanes_used(dssdev) > dsi->num_lanes_supported) { - DSSERR("DSI%d can't support more than %d lanes\n", - dsi_module + 1, dsi->num_lanes_supported); - return -EINVAL; - } - return 0; } -- cgit v0.10.2 From 522a0c2fe58fb6eb145cce07a303857b08322a2b Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Thu, 13 Oct 2011 16:18:52 +0300 Subject: OMAPDSS: DSI: fix lane handling when entering ULPS The current code always enters ULPS for 3 lanes. This is not right, as there could be only 2 lanes used, and on OMAP4 we have 5 lanes. Fix the code to put all used lanes into ULPS. Signed-off-by: Tomi Valkeinen diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c index 2b375c6..22055db 100644 --- a/drivers/video/omap2/dss/dsi.c +++ b/drivers/video/omap2/dss/dsi.c @@ -3517,7 +3517,8 @@ static int dsi_enter_ulps(struct platform_device *dsidev) { struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); DECLARE_COMPLETION_ONSTACK(completion); - int r; + int r, i; + unsigned mask; DSSDBGF(); @@ -3560,10 +3561,16 @@ static int dsi_enter_ulps(struct platform_device *dsidev) if (r) return r; + mask = 0; + + for (i = 0; i < dsi->num_lanes_supported; ++i) { + if (dsi->lanes[i].function == DSI_LANE_UNUSED) + continue; + mask |= 1 << i; + } /* Assert TxRequestEsc for data lanes and TxUlpsClk for clk lane */ /* LANEx_ULPS_SIG2 */ - REG_FLD_MOD(dsidev, DSI_COMPLEXIO_CFG2, (1 << 0) | (1 << 1) | (1 << 2), - 7, 5); + REG_FLD_MOD(dsidev, DSI_COMPLEXIO_CFG2, mask, 9, 5); /* flush posted write and wait for SCP interface to finish the write */ dsi_read_reg(dsidev, DSI_COMPLEXIO_CFG2); @@ -3579,8 +3586,7 @@ static int dsi_enter_ulps(struct platform_device *dsidev) DSI_CIO_IRQ_ULPSACTIVENOT_ALL0); /* Reset LANEx_ULPS_SIG2 */ - REG_FLD_MOD(dsidev, DSI_COMPLEXIO_CFG2, (0 << 0) | (0 << 1) | (0 << 2), - 7, 5); + REG_FLD_MOD(dsidev, DSI_COMPLEXIO_CFG2, 0, 9, 5); /* flush posted write and wait for SCP interface to finish the write */ dsi_read_reg(dsidev, DSI_COMPLEXIO_CFG2); -- cgit v0.10.2 From 3b98409eb7508ce534243312c3a9ac8543c06808 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Thu, 13 Oct 2011 19:06:49 +0300 Subject: OMAPDSS: DSI: improve wait_for_bit_change We sometimes get timeout when disabling the DSI interface with video mode. It looks like the disable will stall until the current frame has been finished, and this can take multiple milliseconds. wait_for_bit_change() currently uses a busyloop to wait for a bit to change. This is used in multiple places. The problem is, we don't have clear understanding how long particular operations can take, so the function needs to support longer waits. Improve wait_for_bit_change() to first busy loop for 100 times to see if the bit changes almost right away. If the bit hasn't changed, move to a loop with a sleep of 1ms, and poll for 500ms. Signed-off-by: Tomi Valkeinen diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c index 22055db..a01a011 100644 --- a/drivers/video/omap2/dss/dsi.c +++ b/drivers/video/omap2/dss/dsi.c @@ -418,14 +418,29 @@ static void dsi_completion_handler(void *data, u32 mask) static inline int wait_for_bit_change(struct platform_device *dsidev, const struct dsi_reg idx, int bitnum, int value) { - int t = 100000; + unsigned long timeout; + ktime_t wait; + int t; + + /* first busyloop to see if the bit changes right away */ + t = 100; + while (t-- > 0) { + if (REG_GET(dsidev, idx, bitnum, bitnum) == value) + return value; + } + + /* then loop for 500ms, sleeping for 1ms in between */ + timeout = jiffies + msecs_to_jiffies(500); + while (time_before(jiffies, timeout)) { + if (REG_GET(dsidev, idx, bitnum, bitnum) == value) + return value; - while (REG_GET(dsidev, idx, bitnum, bitnum) != value) { - if (--t == 0) - return !value; + wait = ns_to_ktime(1000 * 1000); + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_hrtimeout(&wait, HRTIMER_MODE_REL); } - return value; + return !value; } u8 dsi_get_pixel_size(enum omap_dss_dsi_pixel_format fmt) -- cgit v0.10.2 From 6cc78aa9843155c89faa93231332a8b3817020df Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Thu, 13 Oct 2011 19:22:43 +0300 Subject: OMAPDSS: DSI: disable DDR_CLK_ALWAYS_ON when entering ULPS ULPS cannot be entered if the DDR clk is enabled. Thus disable the DDR clk before entering ULPS. Signed-off-by: Tomi Valkeinen diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c index a01a011..9bcb5c2 100644 --- a/drivers/video/omap2/dss/dsi.c +++ b/drivers/video/omap2/dss/dsi.c @@ -3544,9 +3544,11 @@ static int dsi_enter_ulps(struct platform_device *dsidev) if (dsi->ulps_enabled) return 0; + /* DDR_CLK_ALWAYS_ON */ if (REG_GET(dsidev, DSI_CLK_CTRL, 13, 13)) { - DSSERR("DDR_CLK_ALWAYS_ON enabled when entering ULPS\n"); - return -EIO; + dsi_if_enable(dsidev, 0); + REG_FLD_MOD(dsidev, DSI_CLK_CTRL, 0, 13, 13); + dsi_if_enable(dsidev, 1); } dsi_sync_vc(dsidev, 0); -- cgit v0.10.2 From 8754595796a45e88411b68005bc98310c8c6ae76 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Tue, 15 Nov 2011 10:56:11 +0200 Subject: OMAPDSS: DISPC: add missing prototype dispc_mgr_is_enabled() was missing a prototype in dss.h Signed-off-by: Tomi Valkeinen diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h index 6308fc5..3310f10 100644 --- a/drivers/video/omap2/dss/dss.h +++ b/drivers/video/omap2/dss/dss.h @@ -414,6 +414,7 @@ void dispc_mgr_set_cpr_coef(enum omap_channel channel, struct omap_dss_cpr_coefs *coefs); bool dispc_mgr_go_busy(enum omap_channel channel); void dispc_mgr_go(enum omap_channel channel); +bool dispc_mgr_is_enabled(enum omap_channel channel); void dispc_mgr_enable(enum omap_channel channel, bool enable); bool dispc_mgr_is_channel_enabled(enum omap_channel channel); void dispc_mgr_set_io_pad_mode(enum dss_io_pad_mode mode); -- cgit v0.10.2 From 714ad3ac505bba711f961bb8013644c9d8fb486a Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Thu, 27 Oct 2011 13:11:31 +0300 Subject: OMAPDSS: Remove old fifomerge hacks Once in a time omapdss had basic support for fifomerge. Fifomerge was removed as the implementation didn't work properly, and a proper implementation is a complex problem. However, some unused fifo-merge related code was left behind. This patch removes those. Signed-off-by: Tomi Valkeinen diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c index 6e63845..1be5f47 100644 --- a/drivers/video/omap2/dss/manager.c +++ b/drivers/video/omap2/dss/manager.c @@ -1313,8 +1313,6 @@ static int omap_dss_mgr_apply(struct omap_overlay_manager *mgr) struct manager_cache_data *mc; int i; struct omap_overlay *ovl; - int num_planes_enabled = 0; - bool use_fifomerge; unsigned long flags; int r; @@ -1347,11 +1345,8 @@ static int omap_dss_mgr_apply(struct omap_overlay_manager *mgr) continue; } - if (!ovl->info_dirty) { - if (oc->enabled) - ++num_planes_enabled; + if (!ovl->info_dirty) continue; - } dssdev = ovl->manager->device; @@ -1375,8 +1370,6 @@ static int omap_dss_mgr_apply(struct omap_overlay_manager *mgr) oc->channel = ovl->manager->id; oc->enabled = true; - - ++num_planes_enabled; } /* Configure managers */ @@ -1406,21 +1399,6 @@ static int omap_dss_mgr_apply(struct omap_overlay_manager *mgr) dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE; } - /* XXX TODO: Try to get fifomerge working. The problem is that it - * affects both managers, not individually but at the same time. This - * means the change has to be well synchronized. I guess the proper way - * is to have a two step process for fifo merge: - * fifomerge enable: - * 1. disable other planes, leaving one plane enabled - * 2. wait until the planes are disabled on HW - * 3. config merged fifo thresholds, enable fifomerge - * fifomerge disable: - * 1. config unmerged fifo thresholds, disable fifomerge - * 2. wait until fifo changes are in HW - * 3. enable planes - */ - use_fifomerge = false; - /* Configure overlay fifos */ for (i = 0; i < omap_dss_get_num_overlays(); ++i) { struct omap_dss_device *dssdev; @@ -1436,8 +1414,6 @@ static int omap_dss_mgr_apply(struct omap_overlay_manager *mgr) dssdev = ovl->manager->device; size = dispc_ovl_get_fifo_size(ovl->id); - if (use_fifomerge) - size *= 3; burst_size = dispc_ovl_get_burst_size(ovl->id); -- cgit v0.10.2 From b952b553d23912b0b4a496b3e695db5e60c7a99a Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Mon, 31 Oct 2011 13:47:30 +0200 Subject: OMAPDSS: remove L4_EXAMPLE code Some old example code has been left lying around. Remove the example code. Signed-off-by: Tomi Valkeinen diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h index 3310f10..7d2b6dd 100644 --- a/drivers/video/omap2/dss/dss.h +++ b/drivers/video/omap2/dss/dss.h @@ -192,9 +192,6 @@ void dss_init_overlays(struct platform_device *pdev); void dss_uninit_overlays(struct platform_device *pdev); int dss_check_overlay(struct omap_overlay *ovl, struct omap_dss_device *dssdev); void dss_overlay_setup_dispc_manager(struct omap_overlay_manager *mgr); -#ifdef L4_EXAMPLE -void dss_overlay_setup_l4_manager(struct omap_overlay_manager *mgr); -#endif void dss_recheck_connections(struct omap_dss_device *dssdev, bool force); /* DSS */ diff --git a/drivers/video/omap2/dss/overlay.c b/drivers/video/omap2/dss/overlay.c index ab8e40e..d15b826 100644 --- a/drivers/video/omap2/dss/overlay.c +++ b/drivers/video/omap2/dss/overlay.c @@ -641,15 +641,6 @@ void dss_overlay_setup_dispc_manager(struct omap_overlay_manager *mgr) mgr->overlays = dispc_overlays; } -#ifdef L4_EXAMPLE -static struct omap_overlay *l4_overlays[1]; -void dss_overlay_setup_l4_manager(struct omap_overlay_manager *mgr) -{ - mgr->num_overlays = 1; - mgr->overlays = l4_overlays; -} -#endif - void dss_init_overlays(struct platform_device *pdev) { int i, r; @@ -716,33 +707,6 @@ void dss_init_overlays(struct platform_device *pdev) dispc_overlays[i] = ovl; } - -#ifdef L4_EXAMPLE - { - struct omap_overlay *ovl; - ovl = kzalloc(sizeof(*ovl), GFP_KERNEL); - - BUG_ON(ovl == NULL); - - ovl->name = "l4"; - ovl->supported_modes = OMAP_DSS_COLOR_RGB24U; - - ovl->set_manager = &omap_dss_set_manager; - ovl->unset_manager = &omap_dss_unset_manager; - ovl->set_overlay_info = &dss_ovl_set_overlay_info; - ovl->get_overlay_info = &dss_ovl_get_overlay_info; - - omap_dss_add_overlay(ovl); - - r = kobject_init_and_add(&ovl->kobj, &overlay_ktype, - &pdev->dev.kobj, "overlayl4"); - - if (r) - DSSERR("failed to create sysfs file\n"); - - l4_overlays[0] = ovl; - } -#endif } /* connect overlays to the new device, if not already connected. if force -- cgit v0.10.2 From f427984e896fde6ae03056cf1f8ac5d4a99275d4 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Fri, 28 Oct 2011 15:26:26 +0300 Subject: OMAPDSS: DISPC: make dispc_ovl_set_channel_out() public Make dispc_ovl_set_channel_out() public so that later patches can handle changing overlay's manager. Signed-off-by: Tomi Valkeinen diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c index 5bbd838..5130f88 100644 --- a/drivers/video/omap2/dss/dispc.c +++ b/drivers/video/omap2/dss/dispc.c @@ -875,8 +875,7 @@ static void dispc_ovl_set_color_mode(enum omap_plane plane, REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), m, 4, 1); } -static void dispc_ovl_set_channel_out(enum omap_plane plane, - enum omap_channel channel) +void dispc_ovl_set_channel_out(enum omap_plane plane, enum omap_channel channel) { int shift; u32 val; diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h index 7d2b6dd..f899f0f 100644 --- a/drivers/video/omap2/dss/dss.h +++ b/drivers/video/omap2/dss/dss.h @@ -402,6 +402,8 @@ int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi, bool ilace, enum omap_channel channel, bool replication, u32 fifo_low, u32 fifo_high); int dispc_ovl_enable(enum omap_plane plane, bool enable); +void dispc_ovl_set_channel_out(enum omap_plane plane, + enum omap_channel channel); void dispc_mgr_enable_fifohandcheck(enum omap_channel channel, bool enable); -- cgit v0.10.2 From 6f04e1bfc36c5865dc5679f85e25b6613be86298 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Mon, 31 Oct 2011 08:58:52 +0200 Subject: OMAPDSS: DISPC: make dispc_ovl_set_fifo_threshold() public Make dispc_ovl_set_fifo_threshold() public so that later patches can handle overlay fifo configuration. Signed-off-by: Tomi Valkeinen diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c index 5130f88..8249731 100644 --- a/drivers/video/omap2/dss/dispc.c +++ b/drivers/video/omap2/dss/dispc.c @@ -1056,8 +1056,7 @@ u32 dispc_ovl_get_fifo_size(enum omap_plane plane) return dispc.fifo_size[plane]; } -static void dispc_ovl_set_fifo_threshold(enum omap_plane plane, u32 low, - u32 high) +void dispc_ovl_set_fifo_threshold(enum omap_plane plane, u32 low, u32 high) { u8 hi_start, hi_end, lo_start, lo_end; u32 unit; diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h index f899f0f..313a7ca 100644 --- a/drivers/video/omap2/dss/dss.h +++ b/drivers/video/omap2/dss/dss.h @@ -396,6 +396,7 @@ int dispc_calc_clock_rates(unsigned long dispc_fclk_rate, struct dispc_clock_info *cinfo); +void dispc_ovl_set_fifo_threshold(enum omap_plane plane, u32 low, u32 high); u32 dispc_ovl_get_fifo_size(enum omap_plane plane); u32 dispc_ovl_get_burst_size(enum omap_plane plane); int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi, -- cgit v0.10.2 From 8760db5406fb7b92f900d6c98eea198695476467 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Thu, 3 Nov 2011 16:17:37 +0200 Subject: OMAPDSS: remove partial update from the overlay manager Partial update for manual update displays has never worked quite well: * The HW has limitations on the update area, and the x and width need to be even. * Showing a part of a scaled overlay causes artifacts. * Makes the management of dispc very complex Considering the above points and the fact that partial update is not used anywhere, this and the following patches remove the partial update support. This will greatly simplify the following re-write of the apply mechanism to get proper locking and additional features like fifo-merge. This patch removes the partial update from the manager.c. Signed-off-by: Tomi Valkeinen diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c index 9bcb5c2..773a496 100644 --- a/drivers/video/omap2/dss/dsi.c +++ b/drivers/video/omap2/dss/dsi.c @@ -4206,8 +4206,6 @@ int omap_dsi_prepare_update(struct omap_dss_device *dssdev, dsi_perf_mark_setup(dsidev); - dss_setup_partial_planes(dssdev, x, y, w, h, - enlarge_update_area); dispc_mgr_set_lcd_size(dssdev->manager->id, *w, *h); return 0; diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h index 313a7ca..7f6a612 100644 --- a/drivers/video/omap2/dss/dss.h +++ b/drivers/video/omap2/dss/dss.h @@ -182,9 +182,6 @@ void default_get_overlay_fifo_thresholds(enum omap_plane plane, int dss_init_overlay_managers(struct platform_device *pdev); void dss_uninit_overlay_managers(struct platform_device *pdev); int dss_mgr_wait_for_go_ovl(struct omap_overlay *ovl); -void dss_setup_partial_planes(struct omap_dss_device *dssdev, - u16 *x, u16 *y, u16 *w, u16 *h, - bool enlarge_update_area); void dss_start_update(struct omap_dss_device *dssdev); /* overlay */ diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c index 1be5f47..c616f85 100644 --- a/drivers/video/omap2/dss/manager.c +++ b/drivers/video/omap2/dss/manager.c @@ -530,13 +530,6 @@ struct manager_cache_data { bool manual_update; bool do_manual_update; - - /* manual update region */ - u16 x, y, w, h; - - /* enlarge the update area if the update area contains scaled - * overlays */ - bool enlarge_update_area; }; static struct { @@ -762,65 +755,11 @@ static int overlay_enabled(struct omap_overlay *ovl) return ovl->info.enabled && ovl->manager && ovl->manager->device; } -/* Is rect1 a subset of rect2? */ -static bool rectangle_subset(int x1, int y1, int w1, int h1, - int x2, int y2, int w2, int h2) -{ - if (x1 < x2 || y1 < y2) - return false; - - if (x1 + w1 > x2 + w2) - return false; - - if (y1 + h1 > y2 + h2) - return false; - - return true; -} - -/* Do rect1 and rect2 overlap? */ -static bool rectangle_intersects(int x1, int y1, int w1, int h1, - int x2, int y2, int w2, int h2) -{ - if (x1 >= x2 + w2) - return false; - - if (x2 >= x1 + w1) - return false; - - if (y1 >= y2 + h2) - return false; - - if (y2 >= y1 + h1) - return false; - - return true; -} - -static bool dispc_is_overlay_scaled(struct overlay_cache_data *oc) -{ - struct omap_overlay_info *oi = &oc->info; - - if (oi->out_width != 0 && oi->width != oi->out_width) - return true; - - if (oi->out_height != 0 && oi->height != oi->out_height) - return true; - - return false; -} - static int configure_overlay(enum omap_plane plane) { struct overlay_cache_data *c; - struct manager_cache_data *mc; - struct omap_overlay_info *oi, new_oi; - struct omap_overlay_manager_info *mi; - u16 outw, outh; - u16 x, y, w, h; - u32 paddr; + struct omap_overlay_info *oi; int r; - u16 orig_w, orig_h, orig_outw, orig_outh; DSSDBGF("%d", plane); @@ -832,120 +771,7 @@ static int configure_overlay(enum omap_plane plane) return 0; } - mc = &dss_cache.manager_cache[c->channel]; - mi = &mc->info; - - x = oi->pos_x; - y = oi->pos_y; - w = oi->width; - h = oi->height; - outw = oi->out_width == 0 ? oi->width : oi->out_width; - outh = oi->out_height == 0 ? oi->height : oi->out_height; - paddr = oi->paddr; - - orig_w = w; - orig_h = h; - orig_outw = outw; - orig_outh = outh; - - if (mc->manual_update && mc->do_manual_update) { - unsigned bpp; - unsigned scale_x_m = w, scale_x_d = outw; - unsigned scale_y_m = h, scale_y_d = outh; - - /* If the overlay is outside the update region, disable it */ - if (!rectangle_intersects(mc->x, mc->y, mc->w, mc->h, - x, y, outw, outh)) { - dispc_ovl_enable(plane, 0); - return 0; - } - - switch (oi->color_mode) { - case OMAP_DSS_COLOR_NV12: - bpp = 8; - break; - case OMAP_DSS_COLOR_RGB16: - case OMAP_DSS_COLOR_ARGB16: - case OMAP_DSS_COLOR_YUV2: - case OMAP_DSS_COLOR_UYVY: - case OMAP_DSS_COLOR_RGBA16: - case OMAP_DSS_COLOR_RGBX16: - case OMAP_DSS_COLOR_ARGB16_1555: - case OMAP_DSS_COLOR_XRGB16_1555: - bpp = 16; - break; - - case OMAP_DSS_COLOR_RGB24P: - bpp = 24; - break; - - case OMAP_DSS_COLOR_RGB24U: - case OMAP_DSS_COLOR_ARGB32: - case OMAP_DSS_COLOR_RGBA32: - case OMAP_DSS_COLOR_RGBX32: - bpp = 32; - break; - - default: - BUG(); - } - - if (mc->x > oi->pos_x) { - x = 0; - outw -= (mc->x - oi->pos_x); - paddr += (mc->x - oi->pos_x) * - scale_x_m / scale_x_d * bpp / 8; - } else { - x = oi->pos_x - mc->x; - } - - if (mc->y > oi->pos_y) { - y = 0; - outh -= (mc->y - oi->pos_y); - paddr += (mc->y - oi->pos_y) * - scale_y_m / scale_y_d * - oi->screen_width * bpp / 8; - } else { - y = oi->pos_y - mc->y; - } - - if (mc->w < (x + outw)) - outw -= (x + outw) - (mc->w); - - if (mc->h < (y + outh)) - outh -= (y + outh) - (mc->h); - - w = w * outw / orig_outw; - h = h * outh / orig_outh; - - /* YUV mode overlay's input width has to be even and the - * algorithm above may adjust the width to be odd. - * - * Here we adjust the width if needed, preferring to increase - * the width if the original width was bigger. - */ - if ((w & 1) && - (oi->color_mode == OMAP_DSS_COLOR_YUV2 || - oi->color_mode == OMAP_DSS_COLOR_UYVY)) { - if (orig_w > w) - w += 1; - else - w -= 1; - } - } - - new_oi = *oi; - - /* update new_oi members which could have been possibly updated */ - new_oi.pos_x = x; - new_oi.pos_y = y; - new_oi.width = w; - new_oi.height = h; - new_oi.out_width = outw; - new_oi.out_height = outh; - new_oi.paddr = paddr; - - r = dispc_ovl_setup(plane, &new_oi, c->ilace, c->channel, + r = dispc_ovl_setup(plane, oi, c->ilace, c->channel, c->replication, c->fifo_low, c->fifo_high); if (r) { /* this shouldn't happen */ @@ -1070,170 +896,23 @@ static int configure_dispc(void) return r; } -/* Make the coordinates even. There are some strange problems with OMAP and - * partial DSI update when the update widths are odd. */ -static void make_even(u16 *x, u16 *w) -{ - u16 x1, x2; - - x1 = *x; - x2 = *x + *w; - - x1 &= ~1; - x2 = ALIGN(x2, 2); - - *x = x1; - *w = x2 - x1; -} - -/* Configure dispc for partial update. Return possibly modified update - * area */ -void dss_setup_partial_planes(struct omap_dss_device *dssdev, - u16 *xi, u16 *yi, u16 *wi, u16 *hi, bool enlarge_update_area) +void dss_start_update(struct omap_dss_device *dssdev) { - struct overlay_cache_data *oc; struct manager_cache_data *mc; - struct omap_overlay_info *oi; + struct overlay_cache_data *oc; const int num_ovls = dss_feat_get_num_ovls(); + const int num_mgrs = dss_feat_get_num_mgrs(); struct omap_overlay_manager *mgr; int i; - u16 x, y, w, h; - unsigned long flags; - bool area_changed; - - x = *xi; - y = *yi; - w = *wi; - h = *hi; - - DSSDBG("dispc_setup_partial_planes %d,%d %dx%d\n", - *xi, *yi, *wi, *hi); mgr = dssdev->manager; - if (!mgr) { - DSSDBG("no manager\n"); - return; - } - - make_even(&x, &w); - - spin_lock_irqsave(&dss_cache.lock, flags); - - /* - * Execute the outer loop until the inner loop has completed - * once without increasing the update area. This will ensure that - * all scaled overlays end up completely within the update area. - */ - do { - area_changed = false; - - /* We need to show the whole overlay if it is scaled. So look - * for those, and make the update area larger if found. - * Also mark the overlay cache dirty */ - for (i = 0; i < num_ovls; ++i) { - unsigned x1, y1, x2, y2; - unsigned outw, outh; - - oc = &dss_cache.overlay_cache[i]; - oi = &oc->info; - - if (oc->channel != mgr->id) - continue; - - oc->dirty = true; - - if (!enlarge_update_area) - continue; - - if (!oc->enabled) - continue; - - if (!dispc_is_overlay_scaled(oc)) - continue; - - outw = oi->out_width == 0 ? - oi->width : oi->out_width; - outh = oi->out_height == 0 ? - oi->height : oi->out_height; - - /* is the overlay outside the update region? */ - if (!rectangle_intersects(x, y, w, h, - oi->pos_x, oi->pos_y, - outw, outh)) - continue; - - /* if the overlay totally inside the update region? */ - if (rectangle_subset(oi->pos_x, oi->pos_y, outw, outh, - x, y, w, h)) - continue; - - if (x > oi->pos_x) - x1 = oi->pos_x; - else - x1 = x; - - if (y > oi->pos_y) - y1 = oi->pos_y; - else - y1 = y; - - if ((x + w) < (oi->pos_x + outw)) - x2 = oi->pos_x + outw; - else - x2 = x + w; - - if ((y + h) < (oi->pos_y + outh)) - y2 = oi->pos_y + outh; - else - y2 = y + h; - - x = x1; - y = y1; - w = x2 - x1; - h = y2 - y1; - - make_even(&x, &w); - - DSSDBG("changing upd area due to ovl(%d) " - "scaling %d,%d %dx%d\n", - i, x, y, w, h); - - area_changed = true; - } - } while (area_changed); - mc = &dss_cache.manager_cache[mgr->id]; - mc->do_manual_update = true; - mc->enlarge_update_area = enlarge_update_area; - mc->x = x; - mc->y = y; - mc->w = w; - mc->h = h; + mc->do_manual_update = true; configure_dispc(); - mc->do_manual_update = false; - spin_unlock_irqrestore(&dss_cache.lock, flags); - - *xi = x; - *yi = y; - *wi = w; - *hi = h; -} - -void dss_start_update(struct omap_dss_device *dssdev) -{ - struct manager_cache_data *mc; - struct overlay_cache_data *oc; - const int num_ovls = dss_feat_get_num_ovls(); - const int num_mgrs = dss_feat_get_num_mgrs(); - struct omap_overlay_manager *mgr; - int i; - - mgr = dssdev->manager; - for (i = 0; i < num_ovls; ++i) { oc = &dss_cache.overlay_cache[i]; if (oc->channel != mgr->id) diff --git a/drivers/video/omap2/dss/rfbi.c b/drivers/video/omap2/dss/rfbi.c index 1130c60..814bb95 100644 --- a/drivers/video/omap2/dss/rfbi.c +++ b/drivers/video/omap2/dss/rfbi.c @@ -784,7 +784,6 @@ int omap_rfbi_prepare_update(struct omap_dss_device *dssdev, if (*w == 0 || *h == 0) return -EINVAL; - dss_setup_partial_planes(dssdev, x, y, w, h, true); dispc_mgr_set_lcd_size(dssdev->manager->id, *w, *h); return 0; -- cgit v0.10.2 From 5476e74a03f4be972708162050c8ac7fe150449f Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Thu, 3 Nov 2011 16:34:20 +0200 Subject: OMAPDSS: remove partial update from DSI Partial update for manual update displays has never worked quite well: * The HW has limitations on the update area, and the x and width need to be even. * Showing a part of a scaled overlay causes artifacts. * Makes the management of dispc very complex Considering the above points and the fact that partial update is not used anywhere, this and the following patches remove the partial update support. This will greatly simplify the following re-write of the apply mechanism to get proper locking and additional features like fifo-merge. This patch removes the partial update from the dsi.c. Signed-off-by: Tomi Valkeinen diff --git a/drivers/video/omap2/displays/panel-taal.c b/drivers/video/omap2/displays/panel-taal.c index 80c3f6a..0aa6c5d 100644 --- a/drivers/video/omap2/displays/panel-taal.c +++ b/drivers/video/omap2/displays/panel-taal.c @@ -1394,12 +1394,8 @@ static irqreturn_t taal_te_isr(int irq, void *data) if (old) { cancel_delayed_work(&td->te_timeout_work); - r = omap_dsi_update(dssdev, td->channel, - td->update_region.x, - td->update_region.y, - td->update_region.w, - td->update_region.h, - taal_framedone_cb, dssdev); + r = omap_dsi_update(dssdev, td->channel, taal_framedone_cb, + dssdev); if (r) goto err; } @@ -1444,10 +1440,6 @@ static int taal_update(struct omap_dss_device *dssdev, goto err; } - r = omap_dsi_prepare_update(dssdev, &x, &y, &w, &h, true); - if (r) - goto err; - r = taal_set_update_window(td, x, y, w, h); if (r) goto err; @@ -1462,8 +1454,8 @@ static int taal_update(struct omap_dss_device *dssdev, msecs_to_jiffies(250)); atomic_set(&td->do_update, 1); } else { - r = omap_dsi_update(dssdev, td->channel, x, y, w, h, - taal_framedone_cb, dssdev); + r = omap_dsi_update(dssdev, td->channel, taal_framedone_cb, + dssdev); if (r) goto err; } diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c index 773a496..6fc82a4 100644 --- a/drivers/video/omap2/dss/dsi.c +++ b/drivers/video/omap2/dss/dsi.c @@ -238,11 +238,6 @@ enum dsi_vc_source { DSI_VC_SOURCE_VP, }; -struct dsi_update_region { - u16 x, y, w, h; - struct omap_dss_device *device; -}; - struct dsi_irq_stats { unsigned long last_reset; unsigned irq_count; @@ -292,7 +287,9 @@ struct dsi_data { struct dsi_isr_tables isr_tables_copy; int update_channel; - struct dsi_update_region update_region; +#ifdef DEBUG + unsigned update_bytes; +#endif bool te_enabled; bool ulps_enabled; @@ -474,7 +471,6 @@ static void dsi_perf_mark_start(struct platform_device *dsidev) static void dsi_perf_show(struct platform_device *dsidev, const char *name) { struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); - struct omap_dss_device *dssdev = dsi->update_region.device; ktime_t t, setup_time, trans_time; u32 total_bytes; u32 setup_us, trans_us, total_us; @@ -496,9 +492,7 @@ static void dsi_perf_show(struct platform_device *dsidev, const char *name) total_us = setup_us + trans_us; - total_bytes = dsi->update_region.w * - dsi->update_region.h * - dsi_get_pixel_size(dssdev->panel.dsi_pix_fmt) / 8; + total_bytes = dsi->update_bytes; printk(KERN_INFO "DSI(%s): %u us + %u us = %u us (%uHz), " "%u bytes, %u kbytes/sec\n", @@ -4040,7 +4034,7 @@ void dsi_video_mode_disable(struct omap_dss_device *dssdev, int channel) EXPORT_SYMBOL(dsi_video_mode_disable); static void dsi_update_screen_dispc(struct omap_dss_device *dssdev, - u16 x, u16 y, u16 w, u16 h) + u16 w, u16 h) { struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); @@ -4055,8 +4049,7 @@ static void dsi_update_screen_dispc(struct omap_dss_device *dssdev, const unsigned channel = dsi->update_channel; const unsigned line_buf_size = dsi_get_line_buf_size(dsidev); - DSSDBG("dsi_update_screen_dispc(%d,%d %dx%d)\n", - x, y, w, h); + DSSDBG("dsi_update_screen_dispc(%dx%d)\n", w, h); dsi_vc_config_source(dsidev, channel, DSI_VC_SOURCE_VP); @@ -4180,64 +4173,27 @@ static void dsi_framedone_irq_callback(void *data, u32 mask) #endif } -int omap_dsi_prepare_update(struct omap_dss_device *dssdev, - u16 *x, u16 *y, u16 *w, u16 *h, - bool enlarge_update_area) +int omap_dsi_update(struct omap_dss_device *dssdev, int channel, + void (*callback)(int, void *), void *data) { struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); + struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); u16 dw, dh; - dssdev->driver->get_resolution(dssdev, &dw, &dh); - - if (*x > dw || *y > dh) - return -EINVAL; - - if (*x + *w > dw) - return -EINVAL; - - if (*y + *h > dh) - return -EINVAL; - - if (*w == 1) - return -EINVAL; - - if (*w == 0 || *h == 0) - return -EINVAL; - dsi_perf_mark_setup(dsidev); - dispc_mgr_set_lcd_size(dssdev->manager->id, *w, *h); - - return 0; -} -EXPORT_SYMBOL(omap_dsi_prepare_update); - -int omap_dsi_update(struct omap_dss_device *dssdev, - int channel, - u16 x, u16 y, u16 w, u16 h, - void (*callback)(int, void *), void *data) -{ - struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); - struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); - dsi->update_channel = channel; - /* OMAP DSS cannot send updates of odd widths. - * omap_dsi_prepare_update() makes the widths even, but add a BUG_ON - * here to make sure we catch erroneous updates. Otherwise we'll only - * see rather obscure HW error happening, as DSS halts. */ - BUG_ON(x % 2 == 1); - dsi->framedone_callback = callback; dsi->framedone_data = data; - dsi->update_region.x = x; - dsi->update_region.y = y; - dsi->update_region.w = w; - dsi->update_region.h = h; - dsi->update_region.device = dssdev; + dssdev->driver->get_resolution(dssdev, &dw, &dh); - dsi_update_screen_dispc(dssdev, x, y, w, h); +#ifdef DEBUG + dsi->update_bytes = dw * dh * + dsi_get_pixel_size(dssdev->panel.dsi_pix_fmt) / 8; +#endif + dsi_update_screen_dispc(dssdev, dw, dh); return 0; } @@ -4250,6 +4206,7 @@ static int dsi_display_init_dispc(struct omap_dss_device *dssdev) int r; if (dssdev->panel.dsi_mode == OMAP_DSS_DSI_CMD_MODE) { + u16 dw, dh; u32 irq; struct omap_video_timings timings = { .hsw = 1, @@ -4260,6 +4217,10 @@ static int dsi_display_init_dispc(struct omap_dss_device *dssdev) .vbp = 0, }; + dssdev->driver->get_resolution(dssdev, &dw, &dh); + timings.x_res = dw; + timings.y_res = dh; + irq = dssdev->manager->id == OMAP_DSS_CHANNEL_LCD ? DISPC_IRQ_FRAMEDONE : DISPC_IRQ_FRAMEDONE2; diff --git a/include/video/omapdss.h b/include/video/omapdss.h index 378c7ed..60bf426 100644 --- a/include/video/omapdss.h +++ b/include/video/omapdss.h @@ -662,12 +662,7 @@ void omapdss_dsi_vc_enable_hs(struct omap_dss_device *dssdev, int channel, bool enable); int omapdss_dsi_enable_te(struct omap_dss_device *dssdev, bool enable); -int omap_dsi_prepare_update(struct omap_dss_device *dssdev, - u16 *x, u16 *y, u16 *w, u16 *h, - bool enlarge_update_area); -int omap_dsi_update(struct omap_dss_device *dssdev, - int channel, - u16 x, u16 y, u16 w, u16 h, +int omap_dsi_update(struct omap_dss_device *dssdev, int channel, void (*callback)(int, void *), void *data); int omap_dsi_request_vc(struct omap_dss_device *dssdev, int *channel); int omap_dsi_set_vc_id(struct omap_dss_device *dssdev, int channel, int vc_id); -- cgit v0.10.2 From 6331709bcafe578f63c837a8d726ce8ffdfe0895 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Thu, 3 Nov 2011 16:45:07 +0200 Subject: OMAPDSS: remove partial update from panel-taal Partial update for manual update displays has never worked quite well: * The HW has limitations on the update area, and the x and width need to be even. * Showing a part of a scaled overlay causes artifacts. * Makes the management of dispc very complex Considering the above points and the fact that partial update is not used anywhere, this and the following patches remove the partial update support. This will greatly simplify the following re-write of the apply mechanism to get proper locking and additional features like fifo-merge. This patch removes the partial update from the panel-taal.c. Signed-off-by: Tomi Valkeinen diff --git a/drivers/video/omap2/displays/panel-taal.c b/drivers/video/omap2/displays/panel-taal.c index 0aa6c5d..dd64bd1 100644 --- a/drivers/video/omap2/displays/panel-taal.c +++ b/drivers/video/omap2/displays/panel-taal.c @@ -198,12 +198,6 @@ struct taal_data { bool te_enabled; atomic_t do_update; - struct { - u16 x; - u16 y; - u16 w; - u16 h; - } update_region; int channel; struct delayed_work te_timeout_work; @@ -1440,16 +1434,14 @@ static int taal_update(struct omap_dss_device *dssdev, goto err; } - r = taal_set_update_window(td, x, y, w, h); + /* XXX no need to send this every frame, but dsi break if not done */ + r = taal_set_update_window(td, 0, 0, + td->panel_config->timings.x_res, + td->panel_config->timings.y_res); if (r) goto err; if (td->te_enabled && panel_data->use_ext_te) { - td->update_region.x = x; - td->update_region.y = y; - td->update_region.w = w; - td->update_region.h = h; - barrier(); schedule_delayed_work(&td->te_timeout_work, msecs_to_jiffies(250)); atomic_set(&td->do_update, 1); -- cgit v0.10.2 From 1cb0017813e82c740ef7b60bdaa0aa74eaab6a76 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Fri, 18 Nov 2011 11:14:01 +0200 Subject: OMAPDSS: pass ovl manager to dss_start_update dss_start_update() takes currently the dss device as a parameter. Change the parameter to ovl manager, as that is what the dss_start_update() actually needs. Change the name of the function to dss_mgr_start_update() to reflect the change. Signed-off-by: Tomi Valkeinen diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c index 6fc82a4..101e3b8 100644 --- a/drivers/video/omap2/dss/dsi.c +++ b/drivers/video/omap2/dss/dsi.c @@ -4097,7 +4097,7 @@ static void dsi_update_screen_dispc(struct omap_dss_device *dssdev, msecs_to_jiffies(250)); BUG_ON(r == 0); - dss_start_update(dssdev); + dss_mgr_start_update(dssdev->manager); if (dsi->te_enabled) { /* disable LP_RX_TO, so that we can receive TE. Time to wait diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h index 7f6a612..39d4837 100644 --- a/drivers/video/omap2/dss/dss.h +++ b/drivers/video/omap2/dss/dss.h @@ -182,7 +182,7 @@ void default_get_overlay_fifo_thresholds(enum omap_plane plane, int dss_init_overlay_managers(struct platform_device *pdev); void dss_uninit_overlay_managers(struct platform_device *pdev); int dss_mgr_wait_for_go_ovl(struct omap_overlay *ovl); -void dss_start_update(struct omap_dss_device *dssdev); +void dss_mgr_start_update(struct omap_overlay_manager *mgr); /* overlay */ void dss_init_overlays(struct platform_device *pdev); diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c index c616f85..268704b 100644 --- a/drivers/video/omap2/dss/manager.c +++ b/drivers/video/omap2/dss/manager.c @@ -896,17 +896,14 @@ static int configure_dispc(void) return r; } -void dss_start_update(struct omap_dss_device *dssdev) +void dss_mgr_start_update(struct omap_overlay_manager *mgr) { struct manager_cache_data *mc; struct overlay_cache_data *oc; const int num_ovls = dss_feat_get_num_ovls(); const int num_mgrs = dss_feat_get_num_mgrs(); - struct omap_overlay_manager *mgr; int i; - mgr = dssdev->manager; - mc = &dss_cache.manager_cache[mgr->id]; mc->do_manual_update = true; @@ -929,7 +926,7 @@ void dss_start_update(struct omap_dss_device *dssdev) mc->shadow_dirty = false; } - dssdev->manager->enable(dssdev->manager); + mgr->enable(mgr); } static void dss_apply_irq_handler(void *data, u32 mask) -- cgit v0.10.2 From cf0736681e569b0d3803d68d4f6d00f544f3426a Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Thu, 3 Nov 2011 16:08:27 +0200 Subject: OMAPDSS: DISPC: handle 0 out_width/out_height in ovl_setup() Overlay out_width/height are set to 0 when scaling is not used by the users of omapdss. Currently ovl_setup() expects the caller of ovl_setup() to convert those zero values to width or height. This patch makes ovl_setup() accept zero values for out_width/height, making calling ovl_setup() a bit simpler as the overlay_info can be just passed to this function without modifications. Signed-off-by: Tomi Valkeinen diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c index 8249731..f054972 100644 --- a/drivers/video/omap2/dss/dispc.c +++ b/drivers/video/omap2/dss/dispc.c @@ -1781,6 +1781,7 @@ int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi, s32 pix_inc; u16 frame_height = oi->height; unsigned int field_offset = 0; + u16 outw, outh; DSSDBG("dispc_ovl_setup %d, pa %x, pa_uv %x, sw %d, %d,%d, %dx%d -> " "%dx%d, cmode %x, rot %d, mir %d, ilace %d chan %d repl %d " @@ -1792,25 +1793,28 @@ int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi, if (oi->paddr == 0) return -EINVAL; - if (ilace && oi->height == oi->out_height) + outw = oi->out_width == 0 ? oi->width : oi->out_width; + outh = oi->out_height == 0 ? oi->height : oi->out_height; + + if (ilace && oi->height == outh) fieldmode = 1; if (ilace) { if (fieldmode) oi->height /= 2; oi->pos_y /= 2; - oi->out_height /= 2; + outh /= 2; DSSDBG("adjusting for ilace: height %d, pos_y %d, " "out_height %d\n", - oi->height, oi->pos_y, oi->out_height); + oi->height, oi->pos_y, outh); } if (!dss_feat_color_mode_supported(plane, oi->color_mode)) return -EINVAL; r = dispc_ovl_calc_scaling(plane, channel, oi->width, oi->height, - oi->out_width, oi->out_height, oi->color_mode, + outw, outh, oi->color_mode, &five_taps); if (r) return r; @@ -1828,10 +1832,10 @@ int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi, * so the integer part must be added to the base address of the * bottom field. */ - if (!oi->height || oi->height == oi->out_height) + if (!oi->height || oi->height == outh) field_offset = 0; else - field_offset = oi->height / oi->out_height / 2; + field_offset = oi->height / outh / 2; } /* Fields are independent but interleaved in memory. */ @@ -1867,7 +1871,7 @@ int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi, dispc_ovl_set_pix_inc(plane, pix_inc); DSSDBG("%d,%d %dx%d -> %dx%d\n", oi->pos_x, oi->pos_y, oi->width, - oi->height, oi->out_width, oi->out_height); + oi->height, outw, outh); dispc_ovl_set_pos(plane, oi->pos_x, oi->pos_y); @@ -1875,10 +1879,10 @@ int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi, if (ovl->caps & OMAP_DSS_OVL_CAP_SCALE) { dispc_ovl_set_scaling(plane, oi->width, oi->height, - oi->out_width, oi->out_height, + outw, outh, ilace, five_taps, fieldmode, oi->color_mode, oi->rotation); - dispc_ovl_set_vid_size(plane, oi->out_width, oi->out_height); + dispc_ovl_set_vid_size(plane, outw, outh); dispc_ovl_set_vid_color_conv(plane, cconv); } -- cgit v0.10.2 From 3ba2a1c01546a4980e7b7742445560ae4afd1fc1 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Thu, 3 Nov 2011 16:52:06 +0200 Subject: OMAPDSS: handle ilace/replication when configuring overlay Move the configuration of interlace and replication from omap_dss_mgr_apply() to configure_overlay(). This removes the need to store the values into the cache data. Signed-off-by: Tomi Valkeinen diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c index 268704b..d8d0d11 100644 --- a/drivers/video/omap2/dss/manager.c +++ b/drivers/video/omap2/dss/manager.c @@ -510,8 +510,6 @@ struct overlay_cache_data { struct omap_overlay_info info; enum omap_channel channel; - bool replication; - bool ilace; u32 fifo_low; u32 fifo_high; @@ -757,8 +755,10 @@ static int overlay_enabled(struct omap_overlay *ovl) static int configure_overlay(enum omap_plane plane) { + struct omap_overlay *ovl; struct overlay_cache_data *c; struct omap_overlay_info *oi; + bool ilace, replication; int r; DSSDBGF("%d", plane); @@ -771,8 +771,14 @@ static int configure_overlay(enum omap_plane plane) return 0; } - r = dispc_ovl_setup(plane, oi, c->ilace, c->channel, - c->replication, c->fifo_low, c->fifo_high); + ovl = omap_dss_get_overlay(plane); + + replication = dss_use_replication(ovl->manager->device, oi->color_mode); + + ilace = ovl->manager->device->type == OMAP_DISPLAY_TYPE_VENC; + + r = dispc_ovl_setup(plane, oi, ilace, c->channel, + replication, c->fifo_low, c->fifo_high); if (r) { /* this shouldn't happen */ DSSERR("dispc_ovl_setup failed for ovl %d\n", plane); @@ -1038,11 +1044,6 @@ static int omap_dss_mgr_apply(struct omap_overlay_manager *mgr) oc->dirty = true; oc->info = ovl->info; - oc->replication = - dss_use_replication(dssdev, ovl->info.color_mode); - - oc->ilace = dssdev->type == OMAP_DISPLAY_TYPE_VENC; - oc->channel = ovl->manager->id; oc->enabled = true; -- cgit v0.10.2 From f38545da53d98055d8b2f58fe156c86626f3427e Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Thu, 3 Nov 2011 17:00:07 +0200 Subject: OMAPDSS: separate FIFO threshold setup from ovl_setup Overlay FIFO thresholds are configured with ovl_setup, with all the other overlay attributes. This patch separates FIFO threshold setup so that we can later configure FIFO thresholds only when needed. Signed-off-by: Tomi Valkeinen diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c index f054972..094bb6e 100644 --- a/drivers/video/omap2/dss/dispc.c +++ b/drivers/video/omap2/dss/dispc.c @@ -1769,8 +1769,7 @@ static int dispc_ovl_calc_scaling(enum omap_plane plane, } int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi, - bool ilace, enum omap_channel channel, bool replication, - u32 fifo_low, u32 fifo_high) + bool ilace, enum omap_channel channel, bool replication) { struct omap_overlay *ovl = omap_dss_get_overlay(plane); bool five_taps = false; @@ -1784,11 +1783,11 @@ int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi, u16 outw, outh; DSSDBG("dispc_ovl_setup %d, pa %x, pa_uv %x, sw %d, %d,%d, %dx%d -> " - "%dx%d, cmode %x, rot %d, mir %d, ilace %d chan %d repl %d " - "fifo_low %d fifo high %d\n", plane, oi->paddr, oi->p_uv_addr, + "%dx%d, cmode %x, rot %d, mir %d, ilace %d chan %d repl %d\n", + plane, oi->paddr, oi->p_uv_addr, oi->screen_width, oi->pos_x, oi->pos_y, oi->width, oi->height, oi->out_width, oi->out_height, oi->color_mode, oi->rotation, - oi->mirror, ilace, channel, replication, fifo_low, fifo_high); + oi->mirror, ilace, channel, replication); if (oi->paddr == 0) return -EINVAL; @@ -1896,7 +1895,6 @@ int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi, dispc_ovl_set_channel_out(plane, channel); dispc_ovl_enable_replication(plane, replication); - dispc_ovl_set_fifo_threshold(plane, fifo_low, fifo_high); return 0; } diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h index 39d4837..d56e916 100644 --- a/drivers/video/omap2/dss/dss.h +++ b/drivers/video/omap2/dss/dss.h @@ -397,8 +397,7 @@ void dispc_ovl_set_fifo_threshold(enum omap_plane plane, u32 low, u32 high); u32 dispc_ovl_get_fifo_size(enum omap_plane plane); u32 dispc_ovl_get_burst_size(enum omap_plane plane); int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi, - bool ilace, enum omap_channel channel, bool replication, - u32 fifo_low, u32 fifo_high); + bool ilace, enum omap_channel channel, bool replication); int dispc_ovl_enable(enum omap_plane plane, bool enable); void dispc_ovl_set_channel_out(enum omap_plane plane, enum omap_channel channel); diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c index d8d0d11..31637ba 100644 --- a/drivers/video/omap2/dss/manager.c +++ b/drivers/video/omap2/dss/manager.c @@ -777,8 +777,7 @@ static int configure_overlay(enum omap_plane plane) ilace = ovl->manager->device->type == OMAP_DISPLAY_TYPE_VENC; - r = dispc_ovl_setup(plane, oi, ilace, c->channel, - replication, c->fifo_low, c->fifo_high); + r = dispc_ovl_setup(plane, oi, ilace, c->channel, replication); if (r) { /* this shouldn't happen */ DSSERR("dispc_ovl_setup failed for ovl %d\n", plane); @@ -786,6 +785,8 @@ static int configure_overlay(enum omap_plane plane) return r; } + dispc_ovl_set_fifo_threshold(plane, c->fifo_low, c->fifo_high); + dispc_ovl_enable(plane, 1); return 0; -- cgit v0.10.2 From 2cc5d1af5ad0a130fa5812f99bca18e0cdadbd36 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Thu, 3 Nov 2011 17:03:44 +0200 Subject: OMAPDSS: separate overlay channel from ovl_setup Overlay channel is configured with ovl_setup, with all the other overlay attriutes. This patch separates overlay channel setup so that we can later configure the channel only when needed. Signed-off-by: Tomi Valkeinen diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c index 094bb6e..b66cf15 100644 --- a/drivers/video/omap2/dss/dispc.c +++ b/drivers/video/omap2/dss/dispc.c @@ -922,6 +922,39 @@ void dispc_ovl_set_channel_out(enum omap_plane plane, enum omap_channel channel) dispc_write_reg(DISPC_OVL_ATTRIBUTES(plane), val); } +static enum omap_channel dispc_ovl_get_channel_out(enum omap_plane plane) +{ + int shift; + u32 val; + enum omap_channel channel; + + switch (plane) { + case OMAP_DSS_GFX: + shift = 8; + break; + case OMAP_DSS_VIDEO1: + case OMAP_DSS_VIDEO2: + case OMAP_DSS_VIDEO3: + shift = 16; + break; + default: + BUG(); + } + + val = dispc_read_reg(DISPC_OVL_ATTRIBUTES(plane)); + + if (dss_has_feature(FEAT_MGR_LCD2)) { + if (FLD_GET(val, 31, 30) == 0) + channel = FLD_GET(val, shift, shift); + else + channel = OMAP_DSS_CHANNEL_LCD2; + } else { + channel = FLD_GET(val, shift, shift); + } + + return channel; +} + static void dispc_ovl_set_burst_size(enum omap_plane plane, enum omap_burst_size burst_size) { @@ -1769,7 +1802,7 @@ static int dispc_ovl_calc_scaling(enum omap_plane plane, } int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi, - bool ilace, enum omap_channel channel, bool replication) + bool ilace, bool replication) { struct omap_overlay *ovl = omap_dss_get_overlay(plane); bool five_taps = false; @@ -1781,6 +1814,9 @@ int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi, u16 frame_height = oi->height; unsigned int field_offset = 0; u16 outw, outh; + enum omap_channel channel; + + channel = dispc_ovl_get_channel_out(plane); DSSDBG("dispc_ovl_setup %d, pa %x, pa_uv %x, sw %d, %d,%d, %dx%d -> " "%dx%d, cmode %x, rot %d, mir %d, ilace %d chan %d repl %d\n", @@ -1892,8 +1928,6 @@ int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi, dispc_ovl_set_pre_mult_alpha(plane, oi->pre_mult_alpha); dispc_ovl_setup_global_alpha(plane, oi->global_alpha); - dispc_ovl_set_channel_out(plane, channel); - dispc_ovl_enable_replication(plane, replication); return 0; diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h index d56e916..11c72d1 100644 --- a/drivers/video/omap2/dss/dss.h +++ b/drivers/video/omap2/dss/dss.h @@ -397,7 +397,7 @@ void dispc_ovl_set_fifo_threshold(enum omap_plane plane, u32 low, u32 high); u32 dispc_ovl_get_fifo_size(enum omap_plane plane); u32 dispc_ovl_get_burst_size(enum omap_plane plane); int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi, - bool ilace, enum omap_channel channel, bool replication); + bool ilace, bool replication); int dispc_ovl_enable(enum omap_plane plane, bool enable); void dispc_ovl_set_channel_out(enum omap_plane plane, enum omap_channel channel); diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c index 31637ba..ec98e17 100644 --- a/drivers/video/omap2/dss/manager.c +++ b/drivers/video/omap2/dss/manager.c @@ -777,7 +777,9 @@ static int configure_overlay(enum omap_plane plane) ilace = ovl->manager->device->type == OMAP_DISPLAY_TYPE_VENC; - r = dispc_ovl_setup(plane, oi, ilace, c->channel, replication); + dispc_ovl_set_channel_out(plane, c->channel); + + r = dispc_ovl_setup(plane, oi, ilace, replication); if (r) { /* this shouldn't happen */ DSSERR("dispc_ovl_setup failed for ovl %d\n", plane); -- cgit v0.10.2 From c64dca40c5cf1cc61355411dcfb90949e57afdf0 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Fri, 4 Nov 2011 18:14:20 +0200 Subject: OMAPDSS: setup manager with dispc_mgr_setup() Change manager configuration to be similar to overlay configuration by creating dispc_mgr_setup() which takes omap_overlay_manager_info as parameter. Signed-off-by: Tomi Valkeinen diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c index b66cf15..9c070a2 100644 --- a/drivers/video/omap2/dss/dispc.c +++ b/drivers/video/omap2/dss/dispc.c @@ -996,7 +996,7 @@ void dispc_enable_gamma_table(bool enable) REG_FLD_MOD(DISPC_CONFIG, enable, 9, 9); } -void dispc_mgr_enable_cpr(enum omap_channel channel, bool enable) +static void dispc_mgr_enable_cpr(enum omap_channel channel, bool enable) { u16 reg; @@ -1010,7 +1010,7 @@ void dispc_mgr_enable_cpr(enum omap_channel channel, bool enable) REG_FLD_MOD(reg, enable, 15, 15); } -void dispc_mgr_set_cpr_coef(enum omap_channel channel, +static void dispc_mgr_set_cpr_coef(enum omap_channel channel, struct omap_dss_cpr_coefs *coefs) { u32 coef_r, coef_g, coef_b; @@ -2164,7 +2164,7 @@ void dispc_set_loadmode(enum omap_dss_load_mode mode) } -void dispc_mgr_set_default_color(enum omap_channel channel, u32 color) +static void dispc_mgr_set_default_color(enum omap_channel channel, u32 color) { dispc_write_reg(DISPC_DEFAULT_COLOR(channel), color); } @@ -2182,7 +2182,7 @@ u32 dispc_mgr_get_default_color(enum omap_channel channel) return l; } -void dispc_mgr_set_trans_key(enum omap_channel ch, +static void dispc_mgr_set_trans_key(enum omap_channel ch, enum omap_dss_trans_key_type type, u32 trans_key) { @@ -2215,7 +2215,7 @@ void dispc_mgr_get_trans_key(enum omap_channel ch, *trans_key = dispc_read_reg(DISPC_TRANS_COLOR(ch)); } -void dispc_mgr_enable_trans_key(enum omap_channel ch, bool enable) +static void dispc_mgr_enable_trans_key(enum omap_channel ch, bool enable) { if (ch == OMAP_DSS_CHANNEL_LCD) REG_FLD_MOD(DISPC_CONFIG, enable, 10, 10); @@ -2225,7 +2225,8 @@ void dispc_mgr_enable_trans_key(enum omap_channel ch, bool enable) REG_FLD_MOD(DISPC_CONFIG2, enable, 10, 10); } -void dispc_mgr_enable_alpha_fixed_zorder(enum omap_channel ch, bool enable) +static void dispc_mgr_enable_alpha_fixed_zorder(enum omap_channel ch, + bool enable) { if (!dss_has_feature(FEAT_ALPHA_FIXED_ZORDER)) return; @@ -2269,6 +2270,19 @@ bool dispc_mgr_trans_key_enabled(enum omap_channel ch) return enabled; } +void dispc_mgr_setup(enum omap_channel channel, + struct omap_overlay_manager_info *info) +{ + dispc_mgr_set_default_color(channel, info->default_color); + dispc_mgr_set_trans_key(channel, info->trans_key_type, info->trans_key); + dispc_mgr_enable_trans_key(channel, info->trans_enabled); + dispc_mgr_enable_alpha_fixed_zorder(channel, + info->partial_alpha_enabled); + if (dss_has_feature(FEAT_CPR)) { + dispc_mgr_enable_cpr(channel, info->cpr_enable); + dispc_mgr_set_cpr_coef(channel, &info->cpr_coefs); + } +} void dispc_mgr_set_tft_data_lines(enum omap_channel channel, u8 data_lines) { diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h index 11c72d1..a802257 100644 --- a/drivers/video/omap2/dss/dss.h +++ b/drivers/video/omap2/dss/dss.h @@ -405,9 +405,6 @@ void dispc_ovl_set_channel_out(enum omap_plane plane, void dispc_mgr_enable_fifohandcheck(enum omap_channel channel, bool enable); void dispc_mgr_set_lcd_size(enum omap_channel channel, u16 width, u16 height); -void dispc_mgr_enable_cpr(enum omap_channel channel, bool enable); -void dispc_mgr_set_cpr_coef(enum omap_channel channel, - struct omap_dss_cpr_coefs *coefs); bool dispc_mgr_go_busy(enum omap_channel channel); void dispc_mgr_go(enum omap_channel channel); bool dispc_mgr_is_enabled(enum omap_channel channel); @@ -418,16 +415,10 @@ void dispc_mgr_enable_stallmode(enum omap_channel channel, bool enable); void dispc_mgr_set_tft_data_lines(enum omap_channel channel, u8 data_lines); void dispc_mgr_set_lcd_display_type(enum omap_channel channel, enum omap_lcd_display_type type); -void dispc_mgr_set_default_color(enum omap_channel channel, u32 color); u32 dispc_mgr_get_default_color(enum omap_channel channel); -void dispc_mgr_set_trans_key(enum omap_channel ch, - enum omap_dss_trans_key_type type, - u32 trans_key); void dispc_mgr_get_trans_key(enum omap_channel ch, enum omap_dss_trans_key_type *type, u32 *trans_key); -void dispc_mgr_enable_trans_key(enum omap_channel ch, bool enable); -void dispc_mgr_enable_alpha_fixed_zorder(enum omap_channel ch, bool enable); bool dispc_mgr_trans_key_enabled(enum omap_channel ch); bool dispc_mgr_alpha_fixed_zorder_enabled(enum omap_channel ch); void dispc_mgr_set_lcd_timings(enum omap_channel channel, @@ -440,6 +431,8 @@ int dispc_mgr_set_clock_div(enum omap_channel channel, struct dispc_clock_info *cinfo); int dispc_mgr_get_clock_div(enum omap_channel channel, struct dispc_clock_info *cinfo); +void dispc_mgr_setup(enum omap_channel channel, + struct omap_overlay_manager_info *info); /* VENC */ #ifdef CONFIG_OMAP2_DSS_VENC diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c index ec98e17..3421955 100644 --- a/drivers/video/omap2/dss/manager.c +++ b/drivers/video/omap2/dss/manager.c @@ -803,14 +803,7 @@ static void configure_manager(enum omap_channel channel) /* picking info from the cache */ mi = &dss_cache.manager_cache[channel].info; - dispc_mgr_set_default_color(channel, mi->default_color); - dispc_mgr_set_trans_key(channel, mi->trans_key_type, mi->trans_key); - dispc_mgr_enable_trans_key(channel, mi->trans_enabled); - dispc_mgr_enable_alpha_fixed_zorder(channel, mi->partial_alpha_enabled); - if (dss_has_feature(FEAT_CPR)) { - dispc_mgr_enable_cpr(channel, mi->cpr_enable); - dispc_mgr_set_cpr_coef(channel, &mi->cpr_coefs); - } + dispc_mgr_setup(channel, mi); } /* configure_dispc() tries to write values from cache to shadow registers. -- cgit v0.10.2 From c3f96fee1eb8d541b4b5bb841f57bd453c70f12d Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Fri, 4 Nov 2011 18:14:11 +0200 Subject: OMAPDSS: DISPC: remove unused functions Remove unused functions: dispc_mgr_get_default_color dispc_mgr_get_trans_key dispc_mgr_trans_key_enabled dispc_mgr_alpha_fixed_zorder_enabled Signed-off-by: Tomi Valkeinen diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c index 9c070a2..1264c2d 100644 --- a/drivers/video/omap2/dss/dispc.c +++ b/drivers/video/omap2/dss/dispc.c @@ -2169,19 +2169,6 @@ static void dispc_mgr_set_default_color(enum omap_channel channel, u32 color) dispc_write_reg(DISPC_DEFAULT_COLOR(channel), color); } -u32 dispc_mgr_get_default_color(enum omap_channel channel) -{ - u32 l; - - BUG_ON(channel != OMAP_DSS_CHANNEL_DIGIT && - channel != OMAP_DSS_CHANNEL_LCD && - channel != OMAP_DSS_CHANNEL_LCD2); - - l = dispc_read_reg(DISPC_DEFAULT_COLOR(channel)); - - return l; -} - static void dispc_mgr_set_trans_key(enum omap_channel ch, enum omap_dss_trans_key_type type, u32 trans_key) @@ -2196,25 +2183,6 @@ static void dispc_mgr_set_trans_key(enum omap_channel ch, dispc_write_reg(DISPC_TRANS_COLOR(ch), trans_key); } -void dispc_mgr_get_trans_key(enum omap_channel ch, - enum omap_dss_trans_key_type *type, - u32 *trans_key) -{ - if (type) { - if (ch == OMAP_DSS_CHANNEL_LCD) - *type = REG_GET(DISPC_CONFIG, 11, 11); - else if (ch == OMAP_DSS_CHANNEL_DIGIT) - *type = REG_GET(DISPC_CONFIG, 13, 13); - else if (ch == OMAP_DSS_CHANNEL_LCD2) - *type = REG_GET(DISPC_CONFIG2, 11, 11); - else - BUG(); - } - - if (trans_key) - *trans_key = dispc_read_reg(DISPC_TRANS_COLOR(ch)); -} - static void dispc_mgr_enable_trans_key(enum omap_channel ch, bool enable) { if (ch == OMAP_DSS_CHANNEL_LCD) @@ -2237,39 +2205,6 @@ static void dispc_mgr_enable_alpha_fixed_zorder(enum omap_channel ch, REG_FLD_MOD(DISPC_CONFIG, enable, 19, 19); } -bool dispc_mgr_alpha_fixed_zorder_enabled(enum omap_channel ch) -{ - bool enabled; - - if (!dss_has_feature(FEAT_ALPHA_FIXED_ZORDER)) - return false; - - if (ch == OMAP_DSS_CHANNEL_LCD) - enabled = REG_GET(DISPC_CONFIG, 18, 18); - else if (ch == OMAP_DSS_CHANNEL_DIGIT) - enabled = REG_GET(DISPC_CONFIG, 19, 19); - else - BUG(); - - return enabled; -} - -bool dispc_mgr_trans_key_enabled(enum omap_channel ch) -{ - bool enabled; - - if (ch == OMAP_DSS_CHANNEL_LCD) - enabled = REG_GET(DISPC_CONFIG, 10, 10); - else if (ch == OMAP_DSS_CHANNEL_DIGIT) - enabled = REG_GET(DISPC_CONFIG, 12, 12); - else if (ch == OMAP_DSS_CHANNEL_LCD2) - enabled = REG_GET(DISPC_CONFIG2, 10, 10); - else - BUG(); - - return enabled; -} - void dispc_mgr_setup(enum omap_channel channel, struct omap_overlay_manager_info *info) { diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h index a802257..5ac7243 100644 --- a/drivers/video/omap2/dss/dss.h +++ b/drivers/video/omap2/dss/dss.h @@ -415,12 +415,6 @@ void dispc_mgr_enable_stallmode(enum omap_channel channel, bool enable); void dispc_mgr_set_tft_data_lines(enum omap_channel channel, u8 data_lines); void dispc_mgr_set_lcd_display_type(enum omap_channel channel, enum omap_lcd_display_type type); -u32 dispc_mgr_get_default_color(enum omap_channel channel); -void dispc_mgr_get_trans_key(enum omap_channel ch, - enum omap_dss_trans_key_type *type, - u32 *trans_key); -bool dispc_mgr_trans_key_enabled(enum omap_channel ch); -bool dispc_mgr_alpha_fixed_zorder_enabled(enum omap_channel ch); void dispc_mgr_set_lcd_timings(enum omap_channel channel, struct omap_video_timings *timings); void dispc_mgr_set_pol_freq(enum omap_channel channel, -- cgit v0.10.2 From 550a8f646c76f27ede10265b8e4c9d54c9f4af27 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Fri, 4 Nov 2011 13:00:10 +0200 Subject: OMAPDSS: remove unneeded dss_ovl_wait_for_go() There's an unnecessary wrapper function, dss_ovl_wait_for_go(), which does nothing else than call dss_mgr_wait_for_go_ovl(). The dss_ovl_wait_for_go() function can be removed. Signed-off-by: Tomi Valkeinen diff --git a/drivers/video/omap2/dss/overlay.c b/drivers/video/omap2/dss/overlay.c index d15b826..0ab14fa 100644 --- a/drivers/video/omap2/dss/overlay.c +++ b/drivers/video/omap2/dss/overlay.c @@ -548,11 +548,6 @@ static void dss_ovl_get_overlay_info(struct omap_overlay *ovl, *info = ovl->info; } -static int dss_ovl_wait_for_go(struct omap_overlay *ovl) -{ - return dss_mgr_wait_for_go_ovl(ovl); -} - static int omap_dss_set_manager(struct omap_overlay *ovl, struct omap_overlay_manager *mgr) { @@ -689,7 +684,7 @@ void dss_init_overlays(struct platform_device *pdev) ovl->unset_manager = &omap_dss_unset_manager; ovl->set_overlay_info = &dss_ovl_set_overlay_info; ovl->get_overlay_info = &dss_ovl_get_overlay_info; - ovl->wait_for_go = &dss_ovl_wait_for_go; + ovl->wait_for_go = &dss_mgr_wait_for_go_ovl; ovl->caps = dss_feat_get_overlay_caps(ovl->id); ovl->supported_modes = -- cgit v0.10.2 From 32eaa5841021c8d812a4f62898a6e8617d648846 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Fri, 4 Nov 2011 09:04:15 +0200 Subject: OMAPDSS: add ovl/mgr_manual_update() helpers Add helper functions ovl_manual_update() and mgr_manual_update() which return whether the overlay or manager is used with a manual update display. Signed-off-by: Tomi Valkeinen diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c index 3421955..8423cf8 100644 --- a/drivers/video/omap2/dss/manager.c +++ b/drivers/video/omap2/dss/manager.c @@ -538,7 +538,15 @@ static struct { bool irq_enabled; } dss_cache; +static bool ovl_manual_update(struct omap_overlay *ovl) +{ + return ovl->manager->device->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE; +} +static bool mgr_manual_update(struct omap_overlay_manager *mgr) +{ + return mgr->device->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE; +} static int omap_dss_set_device(struct omap_overlay_manager *mgr, struct omap_dss_device *dssdev) @@ -627,7 +635,7 @@ static int dss_mgr_wait_for_go(struct omap_overlay_manager *mgr) if (!dssdev || dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) return 0; - if (dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) + if (mgr_manual_update(mgr)) return 0; if (dssdev->type == OMAP_DISPLAY_TYPE_VENC @@ -696,7 +704,7 @@ int dss_mgr_wait_for_go_ovl(struct omap_overlay *ovl) if (!dssdev || dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) return 0; - if (dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) + if (ovl_manual_update(ovl)) return 0; if (dssdev->type == OMAP_DISPLAY_TYPE_VENC @@ -1047,8 +1055,6 @@ static int omap_dss_mgr_apply(struct omap_overlay_manager *mgr) /* Configure managers */ list_for_each_entry(mgr, &manager_list, list) { - struct omap_dss_device *dssdev; - mc = &dss_cache.manager_cache[mgr->id]; if (mgr->device_changed) { @@ -1062,14 +1068,11 @@ static int omap_dss_mgr_apply(struct omap_overlay_manager *mgr) if (!mgr->device) continue; - dssdev = mgr->device; - mgr->info_dirty = false; mc->dirty = true; mc->info = mgr->info; - mc->manual_update = - dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE; + mc->manual_update = mgr_manual_update(mgr); } /* Configure overlay fifos */ -- cgit v0.10.2 From 209285012c792d3a0f758c7ace30af0ee4bc08a3 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Fri, 4 Nov 2011 09:19:35 +0200 Subject: OMAPDSS: split omap_dss_mgr_apply() to smaller funcs Split omap_dss_mgr_apply() into smaller functions for clarity. Signed-off-by: Tomi Valkeinen diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c index 8423cf8..d0d2315 100644 --- a/drivers/video/omap2/dss/manager.c +++ b/drivers/video/omap2/dss/manager.c @@ -993,107 +993,92 @@ end: spin_unlock(&dss_cache.lock); } -static int omap_dss_mgr_apply(struct omap_overlay_manager *mgr) +static int omap_dss_mgr_apply_ovl(struct omap_overlay *ovl) { struct overlay_cache_data *oc; - struct manager_cache_data *mc; - int i; - struct omap_overlay *ovl; - unsigned long flags; - int r; - - DSSDBG("omap_dss_mgr_apply(%s)\n", mgr->name); + struct omap_dss_device *dssdev; - r = dispc_runtime_get(); - if (r) - return r; + oc = &dss_cache.overlay_cache[ovl->id]; - spin_lock_irqsave(&dss_cache.lock, flags); + if (ovl->manager_changed) { + ovl->manager_changed = false; + ovl->info_dirty = true; + } - /* Configure overlays */ - for (i = 0; i < omap_dss_get_num_overlays(); ++i) { - struct omap_dss_device *dssdev; + if (!overlay_enabled(ovl)) { + if (oc->enabled) { + oc->enabled = false; + oc->dirty = true; + } + return 0; + } - ovl = omap_dss_get_overlay(i); + if (!ovl->info_dirty) + return 0; - oc = &dss_cache.overlay_cache[ovl->id]; + dssdev = ovl->manager->device; - if (ovl->manager_changed) { - ovl->manager_changed = false; - ovl->info_dirty = true; + if (dss_check_overlay(ovl, dssdev)) { + if (oc->enabled) { + oc->enabled = false; + oc->dirty = true; } + return -EINVAL; + } - if (!overlay_enabled(ovl)) { - if (oc->enabled) { - oc->enabled = false; - oc->dirty = true; - } - continue; - } + ovl->info_dirty = false; + oc->dirty = true; + oc->info = ovl->info; - if (!ovl->info_dirty) - continue; + oc->channel = ovl->manager->id; - dssdev = ovl->manager->device; + oc->enabled = true; - if (dss_check_overlay(ovl, dssdev)) { - if (oc->enabled) { - oc->enabled = false; - oc->dirty = true; - } - continue; - } + return 0; +} - ovl->info_dirty = false; - oc->dirty = true; - oc->info = ovl->info; +static void omap_dss_mgr_apply_mgr(struct omap_overlay_manager *mgr) +{ + struct manager_cache_data *mc; - oc->channel = ovl->manager->id; + mc = &dss_cache.manager_cache[mgr->id]; - oc->enabled = true; + if (mgr->device_changed) { + mgr->device_changed = false; + mgr->info_dirty = true; } - /* Configure managers */ - list_for_each_entry(mgr, &manager_list, list) { - mc = &dss_cache.manager_cache[mgr->id]; - - if (mgr->device_changed) { - mgr->device_changed = false; - mgr->info_dirty = true; - } + if (!mgr->info_dirty) + return; - if (!mgr->info_dirty) - continue; + if (!mgr->device) + return; - if (!mgr->device) - continue; + mgr->info_dirty = false; + mc->dirty = true; + mc->info = mgr->info; - mgr->info_dirty = false; - mc->dirty = true; - mc->info = mgr->info; - - mc->manual_update = mgr_manual_update(mgr); - } - - /* Configure overlay fifos */ - for (i = 0; i < omap_dss_get_num_overlays(); ++i) { - struct omap_dss_device *dssdev; - u32 size, burst_size; + mc->manual_update = mgr_manual_update(mgr); +} - ovl = omap_dss_get_overlay(i); +static void omap_dss_mgr_apply_ovl_fifos(struct omap_overlay *ovl) +{ + struct overlay_cache_data *oc; + struct omap_dss_device *dssdev; + u32 size, burst_size; - oc = &dss_cache.overlay_cache[ovl->id]; + oc = &dss_cache.overlay_cache[ovl->id]; - if (!oc->enabled) - continue; + if (!oc->enabled) + return; - dssdev = ovl->manager->device; + dssdev = ovl->manager->device; - size = dispc_ovl_get_fifo_size(ovl->id); + size = dispc_ovl_get_fifo_size(ovl->id); - burst_size = dispc_ovl_get_burst_size(ovl->id); + burst_size = dispc_ovl_get_burst_size(ovl->id); - switch (dssdev->type) { + switch (dssdev->type) { case OMAP_DISPLAY_TYPE_DPI: case OMAP_DISPLAY_TYPE_DBI: case OMAP_DISPLAY_TYPE_SDI: @@ -1112,7 +1097,42 @@ static int omap_dss_mgr_apply(struct omap_overlay_manager *mgr) #endif default: BUG(); - } + } +} + +static int omap_dss_mgr_apply(struct omap_overlay_manager *mgr) +{ + int i, r; + unsigned long flags; + + DSSDBG("omap_dss_mgr_apply(%s)\n", mgr->name); + + r = dispc_runtime_get(); + if (r) + return r; + + spin_lock_irqsave(&dss_cache.lock, flags); + + /* Configure overlays */ + for (i = 0; i < omap_dss_get_num_overlays(); ++i) { + struct omap_overlay *ovl; + + ovl = omap_dss_get_overlay(i); + + omap_dss_mgr_apply_ovl(ovl); + } + + /* Configure managers */ + list_for_each_entry(mgr, &manager_list, list) + omap_dss_mgr_apply_mgr(mgr); + + /* Configure overlay fifos */ + for (i = 0; i < omap_dss_get_num_overlays(); ++i) { + struct omap_overlay *ovl; + + ovl = omap_dss_get_overlay(i); + + omap_dss_mgr_apply_ovl_fifos(ovl); } r = 0; -- cgit v0.10.2 From d2bbb9bbd1503e8b5235fe316e7ee0c7f41daf7e Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Fri, 4 Nov 2011 09:23:10 +0200 Subject: OMAPDSS: apply affects only one overlay manager omap_dss_mgr_apply currently applies settings to all overlays and overlay managers. The reason for this was to support cases where configuration changes affecting multiple managers are made. However, the current code doesn't support changing such configurations, so the functionality is not needed. Change the apply to affect only the manager given as an argument, and the overlays attached to that manager. Signed-off-by: Tomi Valkeinen diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c index d0d2315..d2bdd65 100644 --- a/drivers/video/omap2/dss/manager.c +++ b/drivers/video/omap2/dss/manager.c @@ -1114,23 +1114,28 @@ static int omap_dss_mgr_apply(struct omap_overlay_manager *mgr) spin_lock_irqsave(&dss_cache.lock, flags); /* Configure overlays */ - for (i = 0; i < omap_dss_get_num_overlays(); ++i) { + for (i = 0; i < mgr->num_overlays; ++i) { struct omap_overlay *ovl; - ovl = omap_dss_get_overlay(i); + ovl = mgr->overlays[i]; + + if (ovl->manager != mgr) + continue; omap_dss_mgr_apply_ovl(ovl); } - /* Configure managers */ - list_for_each_entry(mgr, &manager_list, list) - omap_dss_mgr_apply_mgr(mgr); + /* Configure manager */ + omap_dss_mgr_apply_mgr(mgr); /* Configure overlay fifos */ - for (i = 0; i < omap_dss_get_num_overlays(); ++i) { + for (i = 0; i < mgr->num_overlays; ++i) { struct omap_overlay *ovl; - ovl = omap_dss_get_overlay(i); + ovl = mgr->overlays[i]; + + if (ovl->manager != mgr) + continue; omap_dss_mgr_apply_ovl_fifos(ovl); } -- cgit v0.10.2 From 58f2554807a7dc627f1583d1d4363b85758cf685 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Fri, 4 Nov 2011 09:48:54 +0200 Subject: OMAPDSS: create apply.c Create a new file, apply.c, and move code about handling the apply-mechanism and configuration of the managers and overlays from manager.c to apply.c. Not all related code is moved in this patch, but only the core apply/configure functions. The later patches move rest of the code from overlay.c and manager.c, adding necessary locking at the same time. Signed-off-by: Tomi Valkeinen diff --git a/drivers/video/omap2/dss/Makefile b/drivers/video/omap2/dss/Makefile index bd34ac5..8594522 100644 --- a/drivers/video/omap2/dss/Makefile +++ b/drivers/video/omap2/dss/Makefile @@ -1,5 +1,6 @@ obj-$(CONFIG_OMAP2_DSS) += omapdss.o -omapdss-y := core.o dss.o dss_features.o dispc.o display.o manager.o overlay.o +omapdss-y := core.o dss.o dss_features.o dispc.o display.o manager.o overlay.o \ + apply.o omapdss-$(CONFIG_OMAP2_DSS_DPI) += dpi.o omapdss-$(CONFIG_OMAP2_DSS_RFBI) += rfbi.o omapdss-$(CONFIG_OMAP2_DSS_VENC) += venc.o diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c new file mode 100644 index 0000000..c634c98 --- /dev/null +++ b/drivers/video/omap2/dss/apply.c @@ -0,0 +1,656 @@ +/* + * Copyright (C) 2011 Texas Instruments + * Author: Tomi Valkeinen + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . + */ + +#define DSS_SUBSYS_NAME "APPLY" + +#include +#include +#include +#include + +#include