Skip to content
Browse files

SGS yamaha compass driver

  • Loading branch information...
1 parent 36b50b0 commit 1cd83301d17d3c54adc3e361dba778cd9fa2b73a @xcaliburinhand committed Dec 21, 2010
Showing with 267 additions and 0 deletions.
  1. +6 −0 arch/arm/mach-s5pv210/mach-herring.c
  2. +8 −0 drivers/misc/Kconfig
  3. +2 −0 drivers/misc/Makefile
  4. +251 −0 drivers/misc/yamaha.c
View
6 arch/arm/mach-s5pv210/mach-herring.c
@@ -2212,8 +2212,12 @@ static struct i2c_board_info i2c_devs11[] __initdata = {
static struct i2c_board_info i2c_devs12[] __initdata = {
{
+#if defined(CONFIG_SENSORS_YAMAHA)
+ I2C_BOARD_INFO("yamaha", 0x2e),
+#else
I2C_BOARD_INFO("ak8973", 0x1c),
.platform_data = &akm8973_pdata,
+#endif
},
};
@@ -4366,7 +4370,9 @@ static void __init herring_machine_init(void)
gp2a_gpio_init();
i2c_register_board_info(11, i2c_devs11, ARRAY_SIZE(i2c_devs11));
/* magnetic sensor for rev04 */
+#if !defined(CONFIG_SENSORS_YAMAHA)
if (system_rev == 0x04)
+#endif
i2c_register_board_info(12, i2c_devs12, ARRAY_SIZE(i2c_devs12));
/* nfc sensor */
View
8 drivers/misc/Kconfig
@@ -346,6 +346,14 @@ config SENSORS_AK8975
If you say yes here you get support for Asahi Kasei's
orientation sensor AK8975.
+config SENSORS_YAMAHA
+ depends on I2C
+ tristate "YAMAHA"
+ default y
+ help
+ This option enables magnetic sensors using YAMAHA driver.
+ It is optimized for s3c6410.
+
config SENSORS_KR3DM
tristate "KR3DM acceleration sensor support"
depends on I2C
View
2 drivers/misc/Makefile
@@ -43,3 +43,5 @@ obj-$(CONFIG_PN544) += pn544.o
obj-$(CONFIG_SAMSUNG_JACK) += sec_jack.o
obj-$(CONFIG_USB_SWITCH_FSA9480) += fsa9480.o
obj-$(CONFIG_SAMSUNG_MODEMCTL) += samsung_modemctl/
+obj-$(CONFIG_SENSORS_YAMAHA) += yamaha.o
+
View
251 drivers/misc/yamaha.c
@@ -0,0 +1,251 @@
+
+ /*****************************************************************************
+ *
+ * COPYRIGHT(C) : Samsung Electronics Co.Ltd, 2006-2015 ALL RIGHTS RESERVED
+ *
+ *****************************************************************************/
+
+
+//#include <linux/interrupt.h>
+#include <linux/i2c.h>
+#include <linux/slab.h>
+//#include <linux/irq.h>
+#include <linux/miscdevice.h>
+#include <mach/hardware.h>
+#include <asm/uaccess.h>
+#include <linux/delay.h>
+#include <linux/fs.h>
+
+#if defined(CONFIG_GALAXYS_SGH_I897)
+#define YAMAHA_GSENSOR_TRANSFORMATION \
+ { { 0, 1, 0}, \
+ { -1, 0, 0}, \
+ { 0, 0, -1} }
+#else
+#define YAMAHA_GSENSOR_TRANSFORMATION \
+ { { -1, 0, 0}, \
+ { 0, -1, 0}, \
+ { 0, 0, -1} }
+#endif
+
+#if defined(CONFIG_GALAXYS_SGH_I897)
+#define YAMAHA_MSENSOR_TRANSFORMATION \
+ { { 0, 1, 0}, \
+ { -1, 0, 0}, \
+ { 0, 0, 1} }
+#else
+#define YAMAHA_MSENSOR_TRANSFORMATION \
+ { { -1, 0, 0}, \
+ { 0, 1, 0}, \
+ { 0 , 0 , -1} }
+#endif
+
+#define YAMAHA_IOCTL_GET_MARRAY _IOR('Y', 0x01, char [9])
+#define YAMAHA_IOCTL_GET_GARRAY _IOR('Y', 0x02, char [9])
+
+static struct i2c_client *g_client;
+struct yamaha_state *yamaha_state;
+struct yamaha_state{
+ struct i2c_client *client;
+};
+
+static
+yamaha_i2c_write(int len, const uint8_t *buf)
+{
+ return i2c_master_send(g_client, buf, len);
+}
+
+static int
+yamaha_i2c_read(int len, uint8_t *buf)
+{
+ return i2c_master_recv(g_client, buf, len);
+}
+
+static int yamaha_measureRawdata(int32_t *raw)
+{
+ uint8_t dat, buf[6];
+ uint8_t rv = 0;
+ int i;
+
+ dat = 0xC0;
+ if (yamaha_i2c_write(1, &dat) < 0) {
+ return -1;
+ }
+
+ dat = 0x00;
+ if (yamaha_i2c_write(1, &dat) < 0) {
+ return -1;
+ }
+
+ for (i = 0; i < 13; i++) {
+ msleep(1);
+
+ if (yamaha_i2c_read(6, buf) < 0) {
+ return -1;
+ }
+ if (!(buf[0] & 0x80)) {
+ break;
+ }
+ }
+
+ if (buf[0] & 0x80) {
+ return -1;
+ }
+
+ for (i = 0; i < 3; ++i) {
+ raw[2 - i] = ((buf[i << 1] & 0x7) << 8) + buf[(i << 1) | 1];
+ }
+
+ if (raw[0] <= 1024 || raw[0] >= 1) {
+ rv |= 0x1;
+ }
+ if (raw[1] <= 1024 || raw[1] >= 1) {
+ rv |= 0x2;
+ }
+ if (raw[2] <= 1024 || raw[2] >= 1) {
+ rv |= 0x4;
+ }
+
+ return (int)rv;
+}
+
+static int yamaha_open(struct inode *inode, struct file *file)
+{
+ return 0;
+}
+
+static ssize_t
+yamaha_read(struct file *file, char __user * buffer,
+ size_t size, loff_t * pos)
+{
+ int32_t raw[3];
+
+ raw[0] = raw[1] = raw[2] = 0;
+
+ yamaha_measureRawdata(raw);
+
+ return sprintf(buffer, "%d %d %d\n", raw[0], raw[1], raw[2]);
+}
+
+static int yamaha_release(struct inode *inode, struct file *file)
+{
+ return 0;
+}
+
+static int
+yamaha_ioctl(struct inode *inode, struct file *file,
+ unsigned int cmd, unsigned long arg)
+{
+ signed char marray[3][3] = YAMAHA_MSENSOR_TRANSFORMATION;
+ signed char garray[3][3] = YAMAHA_GSENSOR_TRANSFORMATION;
+
+ switch (cmd) {
+ case YAMAHA_IOCTL_GET_MARRAY:
+ if (copy_to_user((void *)arg, marray, sizeof(marray)))
+ {
+ printk("YAMAHA_MSENSOR_TRANSFORMATION copy failed\n");
+ return -EFAULT;
+ }
+ break;
+ case YAMAHA_IOCTL_GET_GARRAY:
+ if (copy_to_user((void *)arg, garray, sizeof(garray)))
+ {
+ printk("YAMAHA_GSENSOR_TRANSFORMATION copy failed\n");
+ return -EFAULT;
+ }
+ break;
+ default:
+ return -ENOTTY;
+ }
+
+ return 0;
+}
+
+static const struct file_operations yamaha_fops = {
+ .owner = THIS_MODULE,
+ .open = yamaha_open,
+ .read = yamaha_read,
+ .release = yamaha_release,
+ .ioctl = yamaha_ioctl,
+};
+
+static struct miscdevice yamaha_device = {
+ .minor = MISC_DYNAMIC_MINOR,
+ .name = "yamaha_compass",
+ .fops = &yamaha_fops,
+};
+
+static int __devinit yamaha_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct yamaha_state *yamaha;
+
+ yamaha = kzalloc(sizeof(struct yamaha_state), GFP_KERNEL);
+ if (yamaha == NULL) {
+ pr_err("%s: failed to allocate memory\n", __func__);
+ return -ENOMEM;
+ }
+
+ yamaha->client = client;
+ i2c_set_clientdata(client, yamaha);
+ g_client = client;
+
+ return 0;
+}
+
+static int __devexit yamaha_remove(struct i2c_client *client)
+{
+ g_client = NULL;
+ return 0;
+}
+
+static const struct i2c_device_id yamaha_ids[] = {
+ { "yamaha", 0 },
+ { }
+};
+
+MODULE_DEVICE_TABLE(i2c, yamaha_ids);
+
+struct i2c_driver yamaha_i2c_driver =
+{
+ .driver = {
+ .name = "yamaha",
+ },
+ .probe = yamaha_probe,
+ .remove = __devexit_p(yamaha_remove),
+ .id_table = yamaha_ids,
+
+};
+
+static int __init yamaha_init(void)
+{
+ int err;
+
+ printk("yamaha_init\n");
+ err = misc_register(&yamaha_device);
+ if (err) {
+ printk("yamaha_init Cannot register miscdev:%d\n",err);
+ return err;
+ }
+
+ if ( (err = i2c_add_driver(&yamaha_i2c_driver)) )
+ {
+ printk("Driver registration failed, module not inserted.\n");
+ return err;
+ }
+
+ return 0;
+}
+
+static void __exit yamaha_exit(void)
+{
+ i2c_del_driver(&yamaha_device);
+ printk("__exit\n");
+}
+
+module_init(yamaha_init);
+module_exit(yamaha_exit);
+
+MODULE_AUTHOR("SAMSUNG");
+MODULE_DESCRIPTION("yamaha compass driver");
+MODULE_LICENSE("GPL");

0 comments on commit 1cd8330

Please sign in to comment.
Something went wrong with that request. Please try again.