|
@@ -0,0 +1,620 @@
+From 0020dc2c6b2164e3104331aa4123d8de6646cf8e Mon Sep 17 00:00:00 2001
+From: Ruediger Gad <r.c.g@gmx.de>
+Date: Sat, 29 Dec 2012 01:04:24 +0100
+Subject: [PATCH] Add support for bcm4751-gps.
+
+This patch was originally taken from:
+https://groups.google.com/forum/?fromgroups=#!topic/linux.kernel/W2mZJcakRmI
+It was originally signed off by:
+Matti J. Aaltonen <matti.j.aaltonen@nokia.com>
+
+The original patch is largely unchanged, only some changes in the Makefile required manual adaptation.
+
+Signed-off-by: Ruediger Gad <r.c.g@gmx.de>
+---
+ drivers/misc/Kconfig | 11 +
+ drivers/misc/Makefile | 1 +
+ drivers/misc/bcm4751-gps.c | 490 ++++++++++++++++++++++++++++++++++++++++
+ include/linux/i2c/bcm4751-gps.h | 59 +++++
+ 4 files changed, 561 insertions(+)
+ create mode 100644 drivers/misc/bcm4751-gps.c
+ create mode 100644 include/linux/i2c/bcm4751-gps.h
+
+diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
+index 85eff54..0400e1b 100644
+--- a/drivers/misc/Kconfig
++++ b/drivers/misc/Kconfig
+@@ -568,6 +568,17 @@ config MAX1749_VIBRATOR
+ ---help---
+ Adds a timed output vibrator device node for MAX1749 vibrator motor
+
++config BCM4751_GPS
++ tristate "BCM4751 GPS driver"
++ depends on I2C
++ default n
++ ---help---
++ If you say yes here you get support for the Broadcom BCM4751 GPS
++ chip driver.
++
++ The driver supports only GPS in BCM4751 chip. When built as a driver
++ driver name is: bcm4751-gps. If unsure, say N here.
++
+ source "drivers/misc/c2port/Kconfig"
+ source "drivers/misc/eeprom/Kconfig"
+ source "drivers/misc/cb710/Kconfig"
+diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
+index 7c26f45..bae6b5f 100644
+--- a/drivers/misc/Makefile
++++ b/drivers/misc/Makefile
+@@ -11,6 +11,7 @@ obj-$(CONFIG_INTEL_MID_PTI) += pti.o
+ obj-$(CONFIG_ATMEL_PWM) += atmel_pwm.o
+ obj-$(CONFIG_ATMEL_SSC) += atmel-ssc.o
+ obj-$(CONFIG_ATMEL_TCLIB) += atmel_tclib.o
++obj-$(CONFIG_BCM4751_GPS) += bcm4751-gps.o
+ obj-$(CONFIG_BMP085) += bmp085.o
+ obj-$(CONFIG_ICS932S401) += ics932s401.o
+ obj-$(CONFIG_LKDTM) += lkdtm.o
+diff --git a/drivers/misc/bcm4751-gps.c b/drivers/misc/bcm4751-gps.c
+new file mode 100644
+index 0000000..d90ec53
+--- /dev/null
++++ b/drivers/misc/bcm4751-gps.c
+@@ -0,0 +1,490 @@
++/*
++ * bcm4751-gps.c - Hardware interface for Broadcom BCM4751 GPS chip.
++ *
++ * Copyright (C) 2010 Nokia Corporation
++ * Contact Matti Aaltonen, matti.j....@nokia.com
++ *
++ * Written by Andrei Emeltchenko <andrei.em...@nokia.com>
++ * Modified by Yuri Zaporozhets <ext-yuri.z...@nokia.com>
++ *
++ * 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, write to the Free Software
++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
++ * 02110-1301 USA
++ */
++
++#define DEBUG
++
++#include <linux/delay.h>
++#include <linux/err.h>
++#include <linux/fs.h>
++#include <linux/gpio.h>
++#include <linux/i2c.h>
++#include <linux/i2c-dev.h>
++#include <linux/interrupt.h>
++#include <linux/kernel.h>
++#include <linux/miscdevice.h>
++#include <linux/module.h>
++#include <linux/mutex.h>
++#include <linux/poll.h>
++#include <linux/regulator/consumer.h>
++#include <linux/slab.h>
++
++#include <linux/i2c/bcm4751-gps.h>
++
++static struct bcm4751_gps_data *bcm4751_gps_device;
++
++static const char reg_vbat[] = "Vbat";
++static const char reg_vddio[] = "Vddio";
++
++/*
++ * Part of initialization is done in the board support file.
++ */
++
++static inline void bcm4751_gps_enable(struct bcm4751_gps_data *self)
++{
++ mutex_lock(&self->mutex);
++ if (!self->enable) {
++ regulator_bulk_enable(ARRAY_SIZE(self->regs), self->regs);
++ if (self->pdata->enable)
++ self->pdata->enable(self->client);
++ self->enable = 1;
++ }
++ mutex_unlock(&self->mutex);
++}
++
++static inline void bcm4751_gps_disable(struct bcm4751_gps_data *self)
++{
++ mutex_lock(&self->mutex);
++ if (self->enable) {
++ if (self->pdata->disable)
++ self->pdata->disable(self->client);
++ self->enable = 0;
++ regulator_bulk_disable(ARRAY_SIZE(self->regs), self->regs);
++ }
++ mutex_unlock(&self->mutex);
++}
++
++static inline void bcm4751_gps_wakeup_value(struct bcm4751_gps_data *self,
++ int value)
++{
++ mutex_lock(&self->mutex);
++ if (self->pdata->wakeup_ctrl)
++ self->pdata->wakeup_ctrl(self->client, value);
++ self->wakeup = value;
++ mutex_unlock(&self->mutex);
++}
++
++
++/*
++ * miscdevice interface
++ */
++
++static int bcm4751_gps_open(struct inode *inode, struct file *file)
++{
++ return 0;
++}
++
++static int bcm4751_gps_release(struct inode *inode, struct file *file)
++{
++ return 0;
++}
++
++static ssize_t bcm4751_gps_read(struct file *file, char __user *buf,
++ size_t count, loff_t *offset)
++{
++ struct i2c_client *client = bcm4751_gps_device->client;
++ int num_read;
++ uint8_t tmp[BCM4751_MAX_BINPKT_RX_LEN];
++
++ /* Adjust for binary packet size */
++ if (count > BCM4751_MAX_BINPKT_RX_LEN)
++ count = BCM4751_MAX_BINPKT_RX_LEN;
++
++ dev_dbg(&client->dev, "reading %d bytes\n", count);
++
++ num_read = i2c_master_recv(client, tmp, count);
++
++ if (num_read < 0) {
++ dev_err(&client->dev, "got %d bytes instead of %d\n",
++ num_read, count);
++ return num_read;
++ } else {
++ dev_dbg(&client->dev, "reading %d bytes returns %d",
++ count, num_read);
++ }
++
++ return copy_to_user(buf, tmp, num_read) ? -EFAULT : num_read;
++}
++
++static ssize_t bcm4751_gps_write(struct file *file, const char __user *buf,
++ size_t count, loff_t *offset)
++{
++ struct i2c_client *client = bcm4751_gps_device->client;
++ uint8_t tmp[BCM4751_MAX_BINPKT_TX_LEN];
++ int num_sent;
++
++ if (count > BCM4751_MAX_BINPKT_TX_LEN)
++ count = BCM4751_MAX_BINPKT_TX_LEN;
|