示例#1
0
static struct smscore_registry_entry_t *smscore_find_registry(char *devpath)
{
	struct smscore_registry_entry_t *entry;
	struct list_head *next;

	kmutex_lock(&g_smscore_registrylock);
	for (next = g_smscore_registry.next; next != &g_smscore_registry; next
			= next->next) {
		entry = (struct smscore_registry_entry_t *) next;
		if (!strcmp(entry->devpath, devpath)) {
			kmutex_unlock(&g_smscore_registrylock);
			return entry;
		}
	}
	entry = kmalloc(
			sizeof(struct smscore_registry_entry_t), GFP_KERNEL);
	if (entry) {
		entry->mode = default_mode;
		if(strlen(devpath) >= 32)
		{
			sms_err(" strlen(devpath) >= 32\n");
			return NULL;
		}
		strcpy(entry->devpath, devpath);
		list_add(&entry->entry, &g_smscore_registry);
	} else
		sms_err("failed to create smscore_registry.");
	kmutex_unlock(&g_smscore_registrylock);
	return entry;
}
示例#2
0
/**
 * copies a firmware buffer from user to kernel space and 
 * keeps a pointer and size on core device.
 *
 * NOTE: this mode type is encouraged and should be used 
 *       only when "request_firmware" is not supported by kernel.
 *
 * @param dev pointer to smschar parameters block
 * @param up pointer to a struct that contains the requested 
 *           pointer to user space fw buffer and it size in bytes
 *
 * @return 0 on success, <0 on error.
 */
int smschar_send_fw_file(struct smschar_device_t *dev,
		struct smschar_send_fw_file_ioctl_t *up) {
	int rc = 0;
	struct smscore_device_t *coredev = dev->coredev;

	sms_debug("fw buffer = 0x%p, size = 0x%x", up->fw_buf, up->fw_size);
	/* free old buffer */
	if (coredev->fw_buf != NULL) {
		kfree(coredev->fw_buf);
		coredev->fw_buf = NULL;
	}

	coredev->fw_buf = kmalloc(ALIGN(up->fw_size, SMS_ALLOC_ALIGNMENT), GFP_KERNEL
			| GFP_DMA);
	if (!coredev->fw_buf) {
		sms_err("failed to allocate memory for fw buffer");
		return -ENOMEM;
	}

	if (copy_from_user(coredev->fw_buf, up->fw_buf, up->fw_size)) {
		sms_err("failed to copy fw from user buffer");
		kfree(coredev->fw_buf);
	        coredev->fw_buf = NULL;
		return -EFAULT;
	}
	coredev->fw_buf_size = up->fw_size;

	return rc;
}
int smsnet_register(void)
{
	int rc;

	INIT_LIST_HEAD(&g_smsnet_clients);
	kmutex_init(&g_smsnet_clientslock);

	memset(&g_smsnet_stats, 0, sizeof(g_smsnet_stats));

	g_smsnet_device = alloc_netdev(0, "sms", smsnet_setup_device);
	if (!g_smsnet_device) {
		sms_err("alloc_netdev() failed");
		return -ENOMEM;
	}

	rc = register_netdev(g_smsnet_device);
	if (rc < 0) {
		sms_err("register_netdev() failed %d\n", rc);
		free_netdev(g_smsnet_device);
		return rc;
	}

	rc = smscore_register_hotplug(smsnet_hotplug);
	sms_info("exit - rc %d", rc);

	return rc;
}
/**
 * Completing Urb's callback handler - bottom half (worker thread context)
 *
 * 1. sends old core buffer to smscore. 
 *    assumes that after return from smsmcore_onsresponse, the core buffer is
 *    either on pendint data (smschar) or in available buffers list (smschar, smsdvb)
 * 2. acquires new available core buffer and submits the urb to the usb core
 *
 * @param surb pointer to a completing surb object
 */
static void smsusb_handle_surb(struct smsusb_urb_t *surb)
{
	struct smsusb_device_t *dev = surb->dev;
	struct urb *urb = &surb->urb;

	if (urb->status == -ESHUTDOWN) {
		sms_err("error, urb status %d (-ESHUTDOWN), %d bytes",
			urb->status, urb->actual_length);
		return;
	}

	/*
	 * in case that the urb was killed during
     * smsusb_stop_streaming, the status is ENOENT
     */
	if (urb->status == -ENOENT) {
		sms_err("error, urb status %d (-ENOENT), %d bytes",
			urb->status, urb->actual_length);
		return;
	}

	if (!dev->surbs_active) {
		sms_err("error, surbs are not active, urb status %d , %d bytes",
			urb->status, urb->actual_length);
		return;	
	}

	if ((urb->actual_length > 0) && (urb->status == 0)) {
		struct SmsMsgHdr_ST *phdr = (struct SmsMsgHdr_ST *)surb->cb->p;

		smsendian_handle_message_header(phdr);
		if (urb->actual_length >= phdr->msgLength) {
			surb->cb->size = phdr->msgLength;

			if (dev->response_alignment &&
			    (phdr->msgFlags & MSG_HDR_FLAG_SPLIT_MSG)) {

				surb->cb->offset =
				    dev->response_alignment +
				    ((phdr->msgFlags >> 8) & 3);

				/* sanity check */
				if (((int)phdr->msgLength +
				     surb->cb->offset) > urb->actual_length) {
					sms_err("invalid response "
						"msglen %d offset %d "
						"size %d",
						phdr->msgLength,
						surb->cb->offset,
						urb->actual_length);
					goto resubmit_and_exit;
				}

				/* move buffer pointer and
				 * copy header to its new location */
				memcpy((char *)phdr + surb->cb->offset,
				       phdr, sizeof(struct SmsMsgHdr_ST));
			} else
示例#5
0
int smsi2c_ts_feed(void *args, unsigned char * ts_buffer, int size) 
{
	struct smscore_device_t *coredev = (struct smscore_device_t *)args;
	struct smscore_buffer_t *cb;
	struct SmsMsgHdr_S *phdr;
	int len = 0;
	int quotient, residue;
	int ts_buf_size_188align;
	sms_debug("%s: buffer:0x%p, size:%d\n", __func__, ts_buffer, size);
if (!size || !args)
		return 0;

#define TS_PACKET_SIZE 188
	ts_buf_size_188align = rounddown((MAX_I2C_BUF_SIZE - sizeof(struct SmsMsgHdr_S)), TS_PACKET_SIZE);
	quotient = size / ts_buf_size_188align;
	residue = size % ts_buf_size_188align;

	for (; quotient > 0; quotient--) {
		cb = smscore_getbuffer(coredev);
		if (!cb) {
			sms_err("Unable to allocate data buffer!\n");
			goto exit;
		}
		phdr = (struct SmsMsgHdr_S *)cb->p;
		memset(cb->p, 0, (int)sizeof(struct SmsMsgHdr_S));
		SMS_INIT_MSG_EX(phdr, MSG_SMS_DAB_CHANNEL, HIF_TASK, 1, ts_buf_size_188align + sizeof(struct SmsMsgHdr_S));
		memcpy((u8*)(phdr+1),ts_buffer, ts_buf_size_188align);
		cb->offset = 0;
		cb->size = ts_buf_size_188align + sizeof(struct SmsMsgHdr_S);
		smscore_onresponse(coredev, cb);
		
		ts_buffer += ts_buf_size_188align;
		len += ts_buf_size_188align;
	}
	if (residue) {
		cb = smscore_getbuffer(coredev);
		if (!cb) {
			sms_err("Unable to allocate data buffer!\n");
			goto exit;
		}
		phdr = (struct SmsMsgHdr_S *)cb->p;
		memset(cb->p, 0, (int)sizeof(struct SmsMsgHdr_S));
		SMS_INIT_MSG_EX(phdr, MSG_SMS_DAB_CHANNEL, HIF_TASK, 1, residue + sizeof(struct SmsMsgHdr_S));
		memcpy((u8*)(phdr+1),ts_buffer, residue);
		cb->offset = 0;
		cb->size = residue + sizeof(struct SmsMsgHdr_S);
		smscore_onresponse(coredev, cb);
		
		ts_buffer += residue;
		len += residue;
	}
	
exit:
	return len;

}
int sms_ir_init(struct smscore_device_t *coredev)
{
	int err;
	int board_id = smscore_get_board_id(coredev);
	struct rc_dev *dev;

	sms_log("Allocating rc device");
	dev = rc_allocate_device();
	if (!dev) {
		sms_err("Not enough memory");
		return -ENOMEM;
	}

	coredev->ir.controller = 0;	
	coredev->ir.timeout = IR_DEFAULT_TIMEOUT;
	sms_log("IR port %d, timeout %d ms",
			coredev->ir.controller, coredev->ir.timeout);

	snprintf(coredev->ir.name, sizeof(coredev->ir.name),
		 "SMS IR (%s)", sms_get_board(board_id)->name);

	strlcpy(coredev->ir.phys, coredev->devpath, sizeof(coredev->ir.phys));
	strlcat(coredev->ir.phys, "/ir0", sizeof(coredev->ir.phys));

	dev->input_name = coredev->ir.name;
	dev->input_phys = coredev->ir.phys;
	dev->dev.parent = coredev->device;

#if 0
	
	dev->input_id.bustype = BUS_USB;
	dev->input_id.version = 1;
	dev->input_id.vendor = le16_to_cpu(dev->udev->descriptor.idVendor);
	dev->input_id.product = le16_to_cpu(dev->udev->descriptor.idProduct);
#endif

	dev->priv = coredev;
	dev->driver_type = RC_DRIVER_IR_RAW;
	dev->allowed_protos = RC_TYPE_ALL;
	dev->map_name = sms_get_board(board_id)->rc_codes;
	dev->driver_name = MODULE_NAME;

	sms_log("Input device (IR) %s is set for key events", dev->input_name);

	err = rc_register_device(dev);
	if (err < 0) {
		sms_err("Failed to register device");
		rc_free_device(dev);
		return err;
	}

	coredev->ir.dev = dev;
	return 0;
}
示例#7
0
/**
 * waits until buffer inserted into a queue. when inserted buffer offset
 * are reportedto the calling process. previously reported buffer is
 * returned to smscore pool.
 *
 * @param dev pointer to smschar parameters block
 * @param touser pointer to a structure that receives incoming buffer offsets
 *
 * @return 0 on success, <0 on error.
 */
static int smschar_wait_get_buffer(struct smschar_device_t *dev,
				   struct smschar_buffer_t *touser)
{
	unsigned long flags;
	int rc;

	spin_lock_irqsave(&dev->lock, flags);

	if (dev->currentcb) {
		smscore_putbuffer(dev->coredev, dev->currentcb);
		dev->currentcb = NULL;
		dev->pending_count--;
	}

	spin_unlock_irqrestore(&dev->lock, flags);

	rc = wait_event_interruptible(dev->waitq,
				      !list_empty(&dev->pending_data)
				      || (dev->cancel_waitq));
	if (rc < 0) {
		sms_err("wait_event_interruptible error, rc = %d", rc);
		return rc;
	}
	if (dev->cancel_waitq) {
		touser->offset = 0;
		touser->size = 0;
		return 0;
	}
	if (!dev->smsclient) {
		sms_err("no client\n");
		return -ENODEV;
	}

	spin_lock_irqsave(&dev->lock, flags);

	if (!list_empty(&dev->pending_data)) {
		struct smscore_buffer_t *cb =
		    (struct smscore_buffer_t *)dev->pending_data.next;
		touser->offset = cb->offset_in_common + cb->offset;
		touser->size = cb->size;

		list_del(&cb->entry);

		dev->currentcb = cb;
	} else {
		touser->offset = 0;
		touser->size = 0;
	}

	spin_unlock_irqrestore(&dev->lock, flags);

	return 0;
}
示例#8
0
/**
 * copies data from buffers in incoming queue into a user buffer
 *
 * @param file File structure.
 * @param buf Source buffer.
 * @param count Size of source buffer.
 * @param f_pos Position in file (ignored).
 *
 * @return Number of bytes read, or <0 on error.
 */
static ssize_t smschar_read(struct file *file, char __user *buf,
			    size_t count, loff_t *f_pos)
{
	struct smschar_device_t *dev = file->private_data;
	unsigned long flags;
	int rc, copied = 0;

	if (!buf) {
		sms_err("bad pointer recieved from user");
		return -EFAULT;
	}
	if (!dev->coredev || !dev->smsclient) {
		sms_err("no client\n");
		return -ENODEV;
	}
	rc = wait_event_interruptible(dev->waitq,
				      !list_empty(&dev->pending_data)
				      || (dev->cancel_waitq));
	if (rc < 0) {
		sms_err("wait_event_interruptible error %d\n", rc);
		return rc;
	}
	if (dev->cancel_waitq)
		return 0;
	if (!dev->smsclient) {
		sms_err("no client\n");
		return -ENODEV;
	}
	spin_lock_irqsave(&dev->lock, flags);

	while (!list_empty(&dev->pending_data) && (copied < count)) {
		struct smscore_buffer_t *cb =
		    (struct smscore_buffer_t *)dev->pending_data.next;
		int actual_size = min(((int)count - copied), cb->size);
		if (copy_to_user(&buf[copied], &((char *)cb->p)[cb->offset],
				 actual_size)) {
			sms_err("copy_to_user failed\n");
			spin_unlock_irqrestore(&dev->lock, flags);
			return -EFAULT;
		}
		copied += actual_size;
		cb->offset += actual_size;
		cb->size -= actual_size;

		if (!cb->size) {
			list_del(&cb->entry);
			smscore_putbuffer(dev->coredev, cb);
			dev->pending_count--;
		}
	}
	spin_unlock_irqrestore(&dev->lock, flags);
	return copied;
}
示例#9
0
/**
 * poll for data availability
 *
 * @param file File structure.
 * @param wait kernel polling table.
 *
 * @return (POLLIN | POLLRDNORM) flags if read data is available.
 *          POLLNVAL flag if wait_queue was cancelled.
 *	    <0 on error.
 */
static unsigned int smschar_poll(struct file *file,
				 struct poll_table_struct *wait)
{
	struct smschar_device_t *dev;
	int events = 0;

	if (file == NULL) {
		sms_err("file is NULL");
		return EINVAL;
	}

	dev = file->private_data;
	if (dev == NULL) {
		sms_err("dev is NULL");
		return -EINVAL;
	}

	if (dev->cancel_waitq) {
		/*sms_debug("returning POLLNVAL");*/
		events |= POLLNVAL;
		return events;
	}

	/*
	 * critical section, protect access to kernel poll
	 * table structure
	 */
	kmutex_lock(&g_smschar_pollwait_lock);

	/*
 	 * make the system call to wait to wait_queue wakeup if there is
	 * no data
	 * cancel_waitq is checked again to prevenet reace condition (wait
	 * to cancalled wait_queue)
	 */
	if (list_empty(&dev->pending_data) && (!dev->cancel_waitq)) {
		poll_wait(file, &dev->waitq, wait);
	}

	/*
	 * pending data, raise relevant flags
	 */
	if (!list_empty(&dev->pending_data)) {
		events |= (POLLIN | POLLRDNORM);
	}
	kmutex_unlock(&g_smschar_pollwait_lock);

	return events;
}
示例#10
0
/**
 * registers client associated with the node
 *
 * @param inode Inode concerned.
 * @param file File concerned.
 *
 * @return 0 on success, <0 on error.
 */
static int smschar_open(struct inode *inode, struct file *file)
{
	struct smschar_device_t *dev = container_of(inode->i_cdev,
						    struct smschar_device_t,
						    cdev);
	int rc = -ENODEV;

	sms_info("entering, device index = %d", dev->device_index);
	if (dev->coredev) {
		struct smsclient_params_t params;
		params.initial_id = dev->device_index ?
		    dev->device_index : SMS_HOST_LIB;
		params.data_type = dev->device_index ? MSG_SMS_DAB_CHANNEL : 0;
		params.onresponse_handler = smschar_onresponse;
		params.onremove_handler = smschar_onremove;
		params.context = dev;

		rc = smscore_register_client(dev->coredev, &params,
					     &dev->smsclient);
		if (!rc)
			file->private_data = dev;
		dev->cancel_waitq = 0;
		g_pnp_status_changed = 1;
	}

	if (rc)
		sms_err("exiting, rc = %d", rc);

	return rc;
}
示例#11
0
/**
 * queues incoming buffers into buffers queue
 *
 * @param context pointer to the client context (smschar parameters block)
 * @param cb pointer to incoming buffer descriptor
 *
 * @return 0 on success, <0 on queue overflow.
 */
static int smschar_onresponse(void *context, struct smscore_buffer_t *cb)
{
	struct smschar_device_t *dev = context;
	unsigned long flags;

	if (!dev) {
		sms_err("recieved bad dev pointer");
		return -EFAULT;
	}
	spin_lock_irqsave(&dev->lock, flags);

	if (dev->pending_count > SMS_CHR_MAX_Q_LEN) {
		spin_unlock_irqrestore(&dev->lock, flags);
		return -EBUSY;
	}

	dev->pending_count++;
	/* if data channel, remove header */
	if (dev->device_index) {
		cb->size -= sizeof(struct SmsMsgHdr_ST);
		cb->offset += sizeof(struct SmsMsgHdr_ST);
	}

	list_add_tail(&cb->entry, &dev->pending_data);
	spin_unlock_irqrestore(&dev->lock, flags);

	if (waitqueue_active(&dev->waitq))
		wake_up_interruptible(&dev->waitq);

	return 0;
}
示例#12
0
static int smsi2c_ts_enable(void *context) {
#define  TS_CLK 4000000 //6000000
//#define  TS_CONTROL_ENABLE

	struct SmsTsEnable_S TsEnableMsg = {{MSG_SMS_ENBALE_TS_INTERFACE_REQ, 
					0, 
					11,
					sizeof(struct SmsTsEnable_S),
					0},
					TS_CLK,//24000000,
					TSI_PARALLEL_ON_HIF, //TSI_PARALLEL_ON_HIF, TSI_SERIAL_ON_SDIO, //wood, ++--, @20140917
					TSI_SIGNALS_ACTIVE_HIGH,//TSI_SIGNALS_ACTIVE_LOW,
					0,//0,
					TSI_SIG_OUT_FALL_EDGE,
					TSI_BIT7_IS_MSB,
#ifdef TS_CONTROL_ENABLE
					1,
#else
					0,
#endif
					TSI_TRANSPARENT,//TSI_ENCAPSULATED,
					21};//21
	struct smsi2c_device *smsdev = (struct smsi2c_device *)context;
	
	if (!smsdev)
	{
		sms_err("smsi2c_ts_enable smsdev NULL!!\n");
		return -ENODEV;
	}
	return smsi2c_sendrequest(context, &TsEnableMsg, sizeof(TsEnableMsg));
	//return i2c_master_normal_send(smsdev->client, &TsEnableMsg, sizeof(TsEnableMsg), I2C_SCL_TATE); //using 400KHz clk

}
示例#13
0
static int smsdvb_update_stats(struct smsdvb_client_t *client,
		struct dvb_frontend *fe) {
	int rc=0;
	unsigned long time_now = jiffies_to_msecs(jiffies);
	
	/*
	 * warning : do not remove this operation mode check
	 * smsdvb_get_statistics_ex will fail on DVBT
	 */
	if  (smscore_get_device_mode(client->coredev) == DEVICE_MODE_DVBT_BDA) {
		return rc;
	}

	if ( (!client->last_sample_time) ||	
	     (time_now - client->last_sample_time > 100) ) 
	{
		/*sms_debug("%lu ms since last sample time, getting statistics",
				(time_now - client->last_sample_time));*/
		rc = smsdvb_get_statistics_ex(fe);
		if (rc < 0) {
			sms_err("error in smsdvb_get_statistics_ex, rc = %d", rc);
			return rc;
		}
	}

	return rc;
}
示例#14
0
int sms_ir_init(struct smscore_device_t *coredev)
{
	struct input_dev *input_dev;

	sms_log("Allocating input device");
	input_dev = input_allocate_device();
	if (!input_dev)	{
		sms_err("Not enough memory");
		return -ENOMEM;
	}

	coredev->ir.input_dev = input_dev;
	coredev->ir.ir_kb_type =
		sms_get_board(smscore_get_board_id(coredev))->ir_kb_type;
	coredev->ir.keyboard_layout_map =
		keyboard_layout_maps[coredev->ir.ir_kb_type].
				keyboard_layout_map;
	sms_log("IR remote keyboard type is %d", coredev->ir.ir_kb_type);

	coredev->ir.controller = 0;	/* Todo: vega/nova SPI number */
	coredev->ir.timeout = IR_DEFAULT_TIMEOUT;
	sms_log("IR port %d, timeout %d ms",
			coredev->ir.controller, coredev->ir.timeout);

	snprintf(coredev->ir.name,
				IR_DEV_NAME_MAX_LEN,
				"SMS IR w/kbd type %d",
				coredev->ir.ir_kb_type);
	input_dev->name = coredev->ir.name;
	input_dev->phys = coredev->ir.name;
	input_dev->dev.parent = coredev->device;

	/* Key press events only */
	input_dev->evbit[0] = BIT_MASK(EV_KEY);
	input_dev->keybit[BIT_WORD(BTN_0)] = BIT_MASK(BTN_0);

	sms_log("Input device (IR) %s is set for key events", input_dev->name);

	if (input_register_device(input_dev)) {
		sms_err("Failed to register device");
		input_free_device(input_dev);
		return -EACCES;
	}

	return 0;
}
示例#15
0
int sms_ir_init(struct smscore_device_t *coredev)
{
	struct input_dev *input_dev;
	int board_id = smscore_get_board_id(coredev);

	sms_log("Allocating input device");
	input_dev = input_allocate_device();
	if (!input_dev)	{
		sms_err("Not enough memory");
		return -ENOMEM;
	}

	coredev->ir.input_dev = input_dev;

	coredev->ir.controller = 0;	/* Todo: vega/nova SPI number */
	coredev->ir.timeout = IR_DEFAULT_TIMEOUT;
	sms_log("IR port %d, timeout %d ms",
			coredev->ir.controller, coredev->ir.timeout);

	snprintf(coredev->ir.name, sizeof(coredev->ir.name),
		 "SMS IR (%s)", sms_get_board(board_id)->name);

	strlcpy(coredev->ir.phys, coredev->devpath, sizeof(coredev->ir.phys));
	strlcat(coredev->ir.phys, "/ir0", sizeof(coredev->ir.phys));

	input_dev->name = coredev->ir.name;
	input_dev->phys = coredev->ir.phys;
	input_dev->dev.parent = coredev->device;


	coredev->ir.props.priv = coredev;
	coredev->ir.props.driver_type = RC_DRIVER_IR_RAW;
	coredev->ir.props.allowed_protos = IR_TYPE_ALL;

	sms_log("Input device (IR) %s is set for key events", input_dev->name);

	if (ir_input_register(input_dev, sms_get_board(board_id)->rc_codes,
			      &coredev->ir.props, MODULE_NAME)) {
		sms_err("Failed to register device");
		input_free_device(input_dev);
		return -EACCES;
	}

	return 0;
}
示例#16
0
static int smsspi_preload(void *context)
{
	struct _smsspi_txmsg msg;
	struct _spi_device_st *spi_device = (struct _spi_device_st *) context;
	struct _Msg Msg = {
		{
		MSG_SMS_SPI_INT_LINE_SET_REQ, 0, HIF_TASK,
			sizeof(struct _Msg), 0}, {
		0, intr_pin, 0}
	};
	int rc;

	prepareForFWDnl(spi_device->phy_dev);
	PDEBUG("Sending SPI init sequence\n");
	msg.buffer = smsspi_startup;
	msg.size = sizeof(smsspi_startup);
	msg.alignment = 4;
	msg.add_preamble = 0;
	msg.prewrite = NULL;	/* smsspiphy_reduce_clock; */
	msg.postwrite = NULL;   /* smsspiphy_restore_clock; */

	rc = smsspi_queue_message_and_wait(context, &msg);
	if (rc < 0) {
		sms_err("smsspi_queue_message_and_wait error, rc=%d\n", rc);
		return rc;
	}

	sms_debug("sending MSG_SMS_SPI_INT_LINE_SET_REQ, time is now %d",\
		jiffies_to_msecs(jiffies));
	PDEBUG("Sending SPI Set Interrupt command sequence\n");
	msg.buffer = &Msg;
	msg.size = sizeof(Msg);
	msg.alignment = SPI_PACKET_SIZE;
	msg.add_preamble = 1;

	rc = smsspi_queue_message_and_wait(context, &msg);
	if (rc < 0) {
		sms_err("smsspi_queue_message_and_wait error, rc=%d\n", rc);
		return rc;
	}

	return rc;
}
示例#17
0
static void smscore_registry_settype(char *devpath,
		enum sms_device_type_st type) {
	struct smscore_registry_entry_t *entry;

	entry = smscore_find_registry(devpath);
	if (entry)
		entry->type = type;
	else
		sms_err("No registry found.");
}
示例#18
0
void smscore_registry_setmode(char *devpath, int mode)
{
	struct smscore_registry_entry_t *entry;

	entry = smscore_find_registry(devpath);
	if (entry)
		entry->mode = mode;
	else
		sms_err("No registry found.");
}
示例#19
0
/* Events that may come from DVB v3 adapter */
static void sms_board_dvb3_event(struct smsdvb_client_t *client,
		enum SMS_DVB3_EVENTS event) {

	struct smscore_device_t *coredev = client->coredev;
	switch (event) {
	case DVB3_EVENT_INIT:
		sms_debug("DVB3_EVENT_INIT");
		sms_board_event(coredev, BOARD_EVENT_BIND);
		break;
	case DVB3_EVENT_SLEEP:
		sms_debug("DVB3_EVENT_SLEEP");
		sms_board_event(coredev, BOARD_EVENT_POWER_SUSPEND);
		break;
	case DVB3_EVENT_HOTPLUG:
		sms_debug("DVB3_EVENT_HOTPLUG");
		sms_board_event(coredev, BOARD_EVENT_POWER_INIT);
		break;
	case DVB3_EVENT_FE_LOCK:
		if (client->event_fe_state != DVB3_EVENT_FE_LOCK)
		{
			client->event_fe_state = DVB3_EVENT_FE_LOCK;
			sms_debug("DVB3_EVENT_FE_LOCK");
			sms_board_event(coredev, BOARD_EVENT_FE_LOCK);
		}
		break;
	case DVB3_EVENT_FE_UNLOCK:
		if (client->event_fe_state != DVB3_EVENT_FE_UNLOCK)
		{
			client->event_fe_state = DVB3_EVENT_FE_UNLOCK;
			sms_debug("DVB3_EVENT_FE_UNLOCK");
			sms_board_event(coredev, BOARD_EVENT_FE_UNLOCK);
		}
		break;
	case DVB3_EVENT_UNC_OK:
		if (client->event_unc_state != DVB3_EVENT_UNC_OK)
		{
			client->event_unc_state = DVB3_EVENT_UNC_OK;
			sms_debug("DVB3_EVENT_UNC_OK");
			sms_board_event(coredev, BOARD_EVENT_MULTIPLEX_OK);
		}
		break;
	case DVB3_EVENT_UNC_ERR:
		if (client->event_unc_state != DVB3_EVENT_UNC_ERR)
		{
			/*client->event_unc_state = DVB3_EVENT_UNC_ERR;*/
			sms_debug("DVB3_EVENT_UNC_ERR");
			sms_board_event(coredev, BOARD_EVENT_MULTIPLEX_ERRORS);
		}
		break;

	default:
		sms_err("Unknown dvb3 api event");
		break;
	}
}
示例#20
0
int sms_board_event(struct smscore_device_t *coredev,
		enum SMS_BOARD_EVENTS gevent) {
	struct smscore_gpio_config MyGpioConfig;

	sms_gpio_assign_11xx_default_led_config(&MyGpioConfig);

	switch (gevent) {
	case BOARD_EVENT_POWER_INIT: /* including hotplug */
		break; /* BOARD_EVENT_BIND */

	case BOARD_EVENT_POWER_SUSPEND:
		break; /* BOARD_EVENT_POWER_SUSPEND */

	case BOARD_EVENT_POWER_RESUME:
		break; /* BOARD_EVENT_POWER_RESUME */

	case BOARD_EVENT_BIND:
		break; /* BOARD_EVENT_BIND */

	case BOARD_EVENT_SCAN_PROG:
		break; /* BOARD_EVENT_SCAN_PROG */
	case BOARD_EVENT_SCAN_COMP:
		break; /* BOARD_EVENT_SCAN_COMP */
	case BOARD_EVENT_EMERGENCY_WARNING_SIGNAL:
		break; /* BOARD_EVENT_EMERGENCY_WARNING_SIGNAL */
	case BOARD_EVENT_FE_LOCK:
		break; /* BOARD_EVENT_FE_LOCK */
	case BOARD_EVENT_FE_UNLOCK:
		break; /* BOARD_EVENT_FE_UNLOCK */
	case BOARD_EVENT_DEMOD_LOCK:
		break; /* BOARD_EVENT_DEMOD_LOCK */
	case BOARD_EVENT_DEMOD_UNLOCK:
		break; /* BOARD_EVENT_DEMOD_UNLOCK */
	case BOARD_EVENT_RECEPTION_MAX_4:
		break; /* BOARD_EVENT_RECEPTION_MAX_4 */
	case BOARD_EVENT_RECEPTION_3:
		break; /* BOARD_EVENT_RECEPTION_3 */
	case BOARD_EVENT_RECEPTION_2:
		break; /* BOARD_EVENT_RECEPTION_2 */
	case BOARD_EVENT_RECEPTION_1:
		break; /* BOARD_EVENT_RECEPTION_1 */
	case BOARD_EVENT_RECEPTION_LOST_0:
		break; /* BOARD_EVENT_RECEPTION_LOST_0 */
	case BOARD_EVENT_MULTIPLEX_OK:
		break; /* BOARD_EVENT_MULTIPLEX_OK */
	case BOARD_EVENT_MULTIPLEX_ERRORS:
		break; /* BOARD_EVENT_MULTIPLEX_ERRORS */

	default:
		sms_err("Unknown SMS board event");
		break;
	}
	return 0;
}
示例#21
0
static enum sms_device_type_st smscore_registry_gettype(char *devpath)
{
	struct smscore_registry_entry_t *entry;

	entry = smscore_find_registry(devpath);
	if (entry)
		return entry->type;
	else
		sms_err("No registry found.");

	return -1;
}
示例#22
0
int smscore_registry_getmode(char *devpath)
{
	struct smscore_registry_entry_t *entry;

	entry = smscore_find_registry(devpath);
	if (entry)
		return entry->mode;
	else
		sms_err("No registry found.");

	return default_mode;
}
示例#23
0
/**
 * sends the buffer to the associated device
 *
 * @param file File structure.
 * @param buf Source buffer.
 * @param count Size of source buffer.
 * @param f_pos Position in file (ignored).
 *
 * @return Number of bytes read, or <0 on error.
 */
static ssize_t smschar_write(struct file *file, const char __user *buf,
			     size_t count, loff_t *f_pos)
{
	struct smschar_device_t *dev;
	void *buffer;

	if (file == NULL) {
		sms_err("file is NULL\n");
		return EINVAL;
	}

	if (file->private_data == NULL) {
		sms_err("file->private_data is NULL\n");
		return -EINVAL;
	}

	dev = file->private_data;
	if (!dev->smsclient) {
		sms_err("no client\n");
		return -ENODEV;
	}

	buffer = kmalloc(ALIGN(count, SMS_ALLOC_ALIGNMENT) + SMS_DMA_ALIGNMENT,
			 GFP_KERNEL | GFP_DMA);
	if (buffer) {
		void *msg_buffer = (void *)SMS_ALIGN_ADDRESS(buffer);

		if (!copy_from_user(msg_buffer, buf, count))
			smsclient_sendrequest(dev->smsclient,
					      msg_buffer, count);
		else
			count = 0;

		kfree(buffer);
	}

	return count;
}
int smsnet_hotplug(struct smscore_device_t *coredev, struct device *device,
		   int arrival)
{
	struct smsclient_params_t params;
	struct smsnet_client_t *client;
	int rc;

	/* device removal handled by onremove callback */
	if (!arrival)
		return 0;

	client = kzalloc(sizeof(struct smsnet_client_t), GFP_KERNEL);
	if (!client) {
		sms_err("kmalloc() failed");
		return -ENOMEM;
	}

	params.initial_id = 1;
	params.data_type = MSG_SMS_DATA_MSG;
	params.onresponse_handler = smsnet_onresponse;
	params.onremove_handler = smsnet_onremove;
	params.context = client;

	rc = smscore_register_client(coredev, &params, &client->smsclient);
	if (rc < 0) {
		sms_err("smscore_register_client() failed %d", rc);
		kfree(client);
		return rc;
	}

	client->coredev = coredev;
	kmutex_lock(&g_smsnet_clientslock);
	list_add(&client->entry, &g_smsnet_clients);
	kmutex_unlock(&g_smsnet_clientslock);
	sms_info("success");
	return 0;
}
示例#25
0
static int smsi2c_sendrequest(void *context, void *buffer, size_t size)
{
	int ret;
	struct smsi2c_device *smsdev = (struct smsi2c_device *)context;
	
	if (!smsdev)
	{
		sms_err("smsi2c_sendrequest smsdev NULL!!\n");
		return -ENODEV;
	}
		
	ret = i2c_master_send(smsdev->client, buffer, (int)size);
	sms_debug("i2c_master_send returned %d", ret);
	return ret;
}
示例#26
0
/**
 * gets firmware filename from look-up table in case 
 * "request_firmware" is not supported by kernel.
 * 
 * @param dev pointer to smschar parameters block
 * @param up pointer to a struct that contains the requested 
 *           mode of operation and a pointer to the filename 
 *           in user space
 *
 * @return 0 on success, <0 on error.
 */
int smschar_get_fw_filename(struct smschar_device_t *dev,
		struct smschar_get_fw_filename_ioctl_t *up) {
	int rc = 0;
	char tmpname[200];

#ifndef REQUEST_FIRMWARE_SUPPORTED
	int mode = up->mode;
	char *fw_filename = smscore_get_fw_filename(dev->coredev, mode,0);
	sprintf(tmpname, "%s/%s", DEFAULT_FW_FILE_PATH, fw_filename);
	sms_debug("need to send fw file %s, mode %d", tmpname, mode);
#else
	/* driver not need file system services */
	tmpname[0] = '\0';
	sms_debug("don't need to send fw file, request firmware supported");
#endif
	if (copy_to_user(up->filename, tmpname, strlen(tmpname) + 1)) {
		sms_err("Failed copy file path to user buffer");
		return -EFAULT;
	}
	return rc;
}
示例#27
0
static int smsdvb_set_frontend(struct dvb_frontend *fe,
			       struct dvb_frontend_parameters *fep)
{
	struct smsdvb_client_t *client =
	    container_of(fe, struct smsdvb_client_t, frontend);

	client->fe_status = FE_HAS_SIGNAL;
	client->event_fe_state = -1;
	client->event_unc_state = -1;

	switch (client->coredev->mode) {
		case DEVICE_MODE_DVBT_BDA:
			return smsdvb_tune_dvbt(client, fep);
		case DEVICE_MODE_ISDBT_BDA:
			return smsdvb_tune_isdbt(client, fep);
		default:
			sms_err("SMS Device mode %d is not set for DVB operation.", client->coredev->mode);
			return -EINVAL;
	}

}
示例#28
0
static int smsi2c_sendrequest(void *context, void *buffer, size_t size)
{
	int ret;
	struct smsi2c_device *smsdev = (struct smsi2c_device *)context;
	
	if (!smsdev)
	{
		sms_err("smsi2c_sendrequest smsdev NULL!!\n");
		return -ENODEV;
	}
#if 0		
	sms_info("Writing message to I2C, size = %d bytes.\n", size);
	sms_info("msg hdr: 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x.\n",
		((u8 *) buffer)[0], ((u8 *) buffer)[1], ((u8 *) buffer)[2],
		((u8 *) buffer)[3], ((u8 *) buffer)[4], ((u8 *) buffer)[5],
		((u8 *) buffer)[6], ((u8 *) buffer)[7]);
#endif
	//ret = i2c_master_send(smsdev->client, buffer, (int)size); 
	ret = i2c_master_normal_send(smsdev->client, buffer, (int)size, I2C_SCL_TATE); //using 400KHz clk
	sms_debug("i2c_master_send returned %d", ret);
	return ret;
}
示例#29
0
int smsdvb_debugfs_register(void)
{
	struct dentry *d;

	/*
	 * FIXME: This was written to debug Siano USB devices. So, it creates
	 * the debugfs node under <debugfs>/usb.
	 * A similar logic would be needed for Siano sdio devices, but, in that
	 * case, usb_debug_root is not a good choice.
	 *
	 * Perhaps the right fix here would be to create another sysfs root
	 * node for sdio-based boards, but this may need some logic at sdio
	 * subsystem.
	 */
	d = debugfs_create_dir("smsdvb", usb_debug_root);
	if (IS_ERR_OR_NULL(d)) {
		sms_err("Couldn't create sysfs node for smsdvb");
		return PTR_ERR(d);
	} else {
		smsdvb_debugfs_usb_root = d;
	}
	return 0;
}
示例#30
0
// allocate and init i2c dev descriptor
// update i2c client params
// 
static int smsi2c_probe(void)
{
	int ret;

	struct smsi2c_device *smsdev;
	struct smsdevice_params_t params;
	struct SmsMsgHdr_S smsmsg;
	struct SmsMsgData2Args_S setIntMsg = {{MSG_SMS_SPI_INT_LINE_SET_REQ, 
				0, 
				11,
				sizeof(struct SmsMsgData2Args_S),
				0},
				{0xff,
				20}};

	    struct i2c_board_info smsi2c_info = {
		I2C_BOARD_INFO("smsi2c", sms_i2c_addr),
	    };
	
	smsdev = kzalloc(sizeof(struct smsi2c_device), GFP_KERNEL);
	if (!smsdev)
	{
		sms_err("Cannot allocate memory for I2C device driver.\n");
		return -ENOMEM;
	}
		
	g_smsi2c_device = smsdev;
	sms_debug ("Memory allocated");
	smsdev->adap = i2c_get_adapter(host_i2c_ctrl);
	if (!smsdev->adap) {
		sms_err("Cannot get adapter #%d.\n", host_i2c_ctrl);
		ret = -ENODEV;
		goto failed_allocate_adapter;
	}
	sms_debug ("Got the adapter");

	smsi2c_info.platform_data = smsdev;

	smsdev->client = i2c_new_device(smsdev->adap, &smsi2c_info);

	if (!smsdev->client) {
		sms_err("Cannot register I2C device with addr 0x%x.\n", sms_i2c_addr);
		 ret = -ENODEV;
		 goto failed_allocate_device;
	}
	sms_debug ("Got the device");


	ret = gpio_request(host_i2c_intr_pin, "sms_gpio");
	if (ret) {
		sms_err("failed to get sms_gpio\n");
		 goto failed_allocate_gpio;
	}	
	gpio_direction_input(host_i2c_intr_pin);
	gpio_export(host_i2c_intr_pin, 0);
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,39)
	irq_set_irq_type(gpio_to_irq(host_i2c_intr_pin), IRQ_TYPE_EDGE_FALLING);	
#else
	set_irq_type(gpio_to_irq(host_i2c_intr_pin), IRQ_TYPE_EDGE_FALLING);	
#endif
	/*register irq*/
	ret = request_irq( gpio_to_irq(host_i2c_intr_pin), (irq_handler_t)smsi2c_interrupt,
		 IRQF_TRIGGER_RISING, "SMSI2C", smsdev);
	if (ret < 0) {
		sms_err("failed to allocate interrupt for SMS\n");
		ret = -ENODEV;
		goto failed_allocate_interrupt;
	}	

	if (device_int_line != 0xFFFFFFFF)
	{ /* Device is not using the default interrupt pin*/

		sms_debug("Device is not using the default int pin, need to set the interrupt pin to %d", device_int_line);
		setIntMsg.msgData[1] = device_int_line;
		ret = smsi2c_sendrequest(smsdev, &setIntMsg, sizeof(setIntMsg));
		msleep(50);
	}

	init_completion(&smsdev->version_ex_done);
	smsdev->wait_for_version_resp = 1;
	SMS_INIT_MSG(&smsmsg, MSG_SMS_GET_VERSION_EX_REQ,
		     sizeof(struct SmsMsgHdr_S));
	smsi2c_sendrequest(smsdev, &smsmsg, sizeof(smsmsg));
	/*Wait for response*/
	ret = wait_for_completion_timeout(&smsdev->version_ex_done, msecs_to_jiffies(500));
	if (ret > 0)
	{ /*Got version. device is in*/
		sms_debug("Found and identified the I2C device");
	}
	else
	{ /* No response recieved*/
		sms_err("No response to get version command");
		ret = -ETIME;
		goto failed_registering_coredev;
	}


	memset(&params, 0, sizeof(struct smsdevice_params_t));

	params.device = (struct device *)&smsdev->client->adapter->dev;
#ifdef SMS_RK_TS
	params.buffer_size = MAX_I2C_BUF_SIZE;
	params.num_buffers = MAX_I2C_BUF_NUMBER;
	params.require_node_buffer = 1;
#else
	params.buffer_size = 0x400;
	params.num_buffers = 20;
#endif
	params.context = smsdev;

	snprintf(params.devpath, sizeof(params.devpath),
		 "i2c\\%s", "smsi2c");

	params.sendrequest_handler  = smsi2c_sendrequest;
	params.loadfirmware_handler = smsi2c_loadfirmware_handler;
	switch(smsdev->chip_model)
	{
		case 0: params.device_type = 0; break;
		case 0x1002:
		case 0x1102:
		case 0x1004: params.device_type = SMS_NOVA_B0; break;
		case 0x1182: params.device_type = SMS_VENICE; break;
		case 0x1530: params.device_type = SMS_DENVER_1530; break;
		case 0x2130: params.device_type = SMS_PELE; break;
		case 0x2160: params.device_type = SMS_DENVER_2160; break;
		case 0x2180: params.device_type = SMS_MING; break;
		case 0x2230: params.device_type = SMS_RIO; break;
		case 0x3130: params.device_type = SMS_ZICO; break;
		case 0x3180: params.device_type = SMS_QING; break;
		case 0x3230: params.device_type = SMS_SANTOS; break;
		case 0x4470: 
			if (smsdev->chip_metal >= 2)
				params.device_type = SMS_SIENA_A2; 
			else
				params.device_type = SMS_SIENA; 
			break;

		default: params.device_type = 0; break;
	}

	/* Use SMS_DEVICE_FAMILY2 for firmware download over SMS MSGs
	   SMS_DEVICE_FAMILY1 for backdoor I2C firmware download */
	params.flags |= SMS_DEVICE_FAMILY2;
	
	/* Device protocol completion events */

	ret = smscore_register_device(&params, &smsdev->coredev);
	if (ret < 0)
        {
	        printk(KERN_INFO "smscore_register_device error\n");
		goto failed_registering_coredev;
        }

	ret = smscore_start_device(smsdev->coredev);
	if (ret < 0)
        {
		printk(KERN_INFO "smscore_start_device error\n");
		goto failed_device_start;
        }

	return 0;
failed_device_start:
	smscore_unregister_device(smsdev->coredev);
failed_registering_coredev:
	free_irq(gpio_to_irq(host_i2c_intr_pin), smsdev);
failed_allocate_interrupt:
	gpio_free(host_i2c_intr_pin);
failed_allocate_gpio:
	i2c_unregister_device(smsdev->client);
failed_allocate_device:
	i2c_put_adapter(smsdev->adap);
failed_allocate_adapter:
	g_smsi2c_device = NULL;
	kfree(smsdev);

	return ret;
}