ThJap

diff 4.1.B.0.431 - 4.1.B.0.479

Jun 28th, 2012
283
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Diff 209.44 KB | None | 0 0
  1. diff -ruN a/4.1.B.0.431//external/webkit/Source/WebCore/rendering/RenderImage.cpp b/4.1.B.0.479//external/webkit/Source/WebCore/rendering/RenderImage.cpp
  2. --- a/4.1.B.0.431//external/webkit/Source/WebCore/rendering/RenderImage.cpp 2012-05-25 19:07:01.000000000 +0900
  3. +++ b/4.1.B.0.479//external/webkit/Source/WebCore/rendering/RenderImage.cpp 2012-06-25 19:47:11.000000000 +0900
  4. @@ -8,6 +8,7 @@
  5.   * Copyright (C) 2010 Google Inc. All rights reserved.
  6.   *
  7.   * Portions created by Sony Ericsson are Copyright (C) 2011 Sony Ericsson Mobile Communications AB.
  8. + * Copyright (C) 2012 Sony Mobile Communications AB.
  9.   * All Rights Reserved.
  10.   *
  11.   * This library is free software; you can redistribute it and/or
  12. @@ -572,17 +573,32 @@
  13.  #endif
  14.  }
  15.  
  16. +/**
  17. + * A version of RenderBox::computeReplacedLogicalHeight that ignores
  18. + * a percentage height when there is no specified height on the containing block.
  19. + */
  20. +int RenderImage::renderBoxComputeReplacedLogicalHeight() const
  21. +{
  22. +    int logicalHeight = isLogicalHeightSpecified() ?
  23. +        RenderBox::computeReplacedLogicalHeightUsing(style()->logicalHeight()) :
  24. +        intrinsicLogicalHeight();
  25. +    int minLogicalHeight =
  26. +        RenderBox::computeReplacedLogicalHeightUsing(style()->logicalMinHeight());
  27. +    int maxLogicalHeight = style()->logicalMaxHeight().isUndefined() ? logicalHeight :
  28. +        RenderBox::computeReplacedLogicalHeightUsing(style()->logicalMaxHeight());
  29. +
  30. +    return max(minLogicalHeight, min(logicalHeight, maxLogicalHeight));
  31. +}
  32. +
  33.  int RenderImage::calcAspectRatioLogicalWidth() const
  34.  {
  35.      int intrinsicWidth = intrinsicLogicalWidth();
  36.      int intrinsicHeight = intrinsicLogicalHeight();
  37.      if (!intrinsicHeight)
  38.          return 0;
  39. -    // [SonyEricsson]: Do not scale if no height is specified.
  40. -    if (!m_imageResource->hasImage() || m_imageResource->errorOccurred() ||
  41. -            !isLogicalHeightSpecified())
  42. +    if (!m_imageResource->hasImage() || m_imageResource->errorOccurred())
  43.          return intrinsicWidth; // Don't bother scaling.
  44. -    return RenderBox::computeReplacedLogicalHeight() * intrinsicWidth / intrinsicHeight;
  45. +    return renderBoxComputeReplacedLogicalHeight() * intrinsicWidth / intrinsicHeight;
  46.  }
  47.  
  48.  int RenderImage::calcAspectRatioLogicalHeight() const
  49. diff -ruN a/4.1.B.0.431//external/webkit/Source/WebCore/rendering/RenderImage.h b/4.1.B.0.479//external/webkit/Source/WebCore/rendering/RenderImage.h
  50. --- a/4.1.B.0.431//external/webkit/Source/WebCore/rendering/RenderImage.h   2012-05-25 19:07:01.000000000 +0900
  51. +++ b/4.1.B.0.479//external/webkit/Source/WebCore/rendering/RenderImage.h   2012-06-25 19:47:11.000000000 +0900
  52. @@ -4,6 +4,7 @@
  53.   *           (C) 2006 Allan Sandfeld Jensen ([email protected])
  54.   *           (C) 2006 Samuel Weinig ([email protected])
  55.   * Copyright (C) 2004, 2005, 2006, 2007, 2009, 2010, 2011 Apple Inc. All rights reserved.
  56. + * Copyright (C) 2012 Sony Mobile Communications AB.
  57.   *
  58.   * This library is free software; you can redistribute it and/or
  59.   * modify it under the terms of the GNU Library General Public
  60. @@ -85,6 +86,7 @@
  61.  
  62.      virtual int computeReplacedLogicalWidth(bool includeMaxWidth = true) const;
  63.      virtual int computeReplacedLogicalHeight() const;
  64. +    int renderBoxComputeReplacedLogicalHeight() const;
  65.  
  66.      IntSize imageSizeForError(CachedImage*) const;
  67.      void imageDimensionsChanged(bool imageSizeChanged, const IntRect* = 0);
  68. diff -ruN a/4.1.B.0.431//kernel/arch/arm/mach-msm/board-semc_zeus.c b/4.1.B.0.479//kernel/arch/arm/mach-msm/board-semc_zeus.c
  69. --- a/4.1.B.0.431//kernel/arch/arm/mach-msm/board-semc_zeus.c   2012-06-10 23:35:47.000000000 +0900
  70. +++ b/4.1.B.0.479//kernel/arch/arm/mach-msm/board-semc_zeus.c   2012-06-25 19:47:11.000000000 +0900
  71. @@ -1132,6 +1132,12 @@
  72.     .cdrom_vendor   = "SEMC",
  73.     .cdrom_product  = "CD-ROM",
  74.     .cdrom_release  = 0x0100,
  75. +
  76. +   /* EUI-64 based identifier format */
  77. +   .eui64_id = {
  78. +       .ieee_company_id = {0x00, 0x0A, 0xD9},
  79. +       .vendor_specific_ext_field = {0x00, 0x00, 0x00, 0x00, 0x00},
  80. +   },
  81.  };
  82.  
  83.  static struct platform_device mass_storage_device = {
  84. diff -ruN a/4.1.B.0.431//kernel/drivers/input/touchscreen/cy8ctma300_spi.c b/4.1.B.0.479//kernel/drivers/input/touchscreen/cy8ctma300_spi.c
  85. --- a/4.1.B.0.431//kernel/drivers/input/touchscreen/cy8ctma300_spi.c    2012-05-25 19:07:09.000000000 +0900
  86. +++ b/4.1.B.0.479//kernel/drivers/input/touchscreen/cy8ctma300_spi.c    2012-06-25 19:47:11.000000000 +0900
  87. @@ -823,12 +823,6 @@
  88.     memset(&tp->track_detect[0], TP_FNGR_NOTRACK,
  89.                         ARRAY_SIZE(tp->track_detect));
  90.  
  91. -   if (fdetect) {
  92. -       input_report_key(tp->input, BTN_TOUCH, 1);
  93. -   } else {
  94. -       input_report_key(tp->input, BTN_TOUCH, 0);
  95. -   }
  96. -
  97.     for (i = 0; i < TP_TOUCH_CNT_MAX; i++) {
  98.         if (tp->track_state[i] == TP_TRACK_ACTIVE)
  99.             cy8ctma300_update_track(tp, i, cur_touch, fdetect);
  100. @@ -840,9 +834,13 @@
  101.             touch_major = 0;
  102.             pressure = 0;
  103.             tp->track_state[i] = TP_TRACK_INACTIVE;
  104. -           report = 1;
  105. +           report = 0;
  106.             dev_dbg(&tp->spi->dev, "%s: MT report removed "
  107.                         "finger\n", __func__);
  108. +
  109. +           if (!fdetect) {
  110. +               input_mt_sync(tp->input);
  111. +           }
  112.         } else if (tp->track_state[i] == TP_TRACK_ACTIVE) {
  113.             width_major = pdata->width_major;
  114.             touch_major = min((width_major * tp->mt_pos[i].z
  115. @@ -1920,7 +1918,6 @@
  116.     dev->dev.parent = &spi->dev;
  117.  
  118.     dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
  119. -   dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
  120.     dev->absbit[BIT_WORD(ABS_MT_TRACKING_ID)] |=
  121.                         BIT_MASK(ABS_MT_TRACKING_ID);
  122.  
  123. diff -ruN a/4.1.B.0.431//kernel/drivers/input/touchscreen/cyttsp_core.c b/4.1.B.0.479//kernel/drivers/input/touchscreen/cyttsp_core.c
  124. --- a/4.1.B.0.431//kernel/drivers/input/touchscreen/cyttsp_core.c   2012-06-10 23:35:47.000000000 +0900
  125. +++ b/4.1.B.0.479//kernel/drivers/input/touchscreen/cyttsp_core.c   2012-06-25 19:47:11.000000000 +0900
  126. @@ -644,7 +644,7 @@
  127.  
  128.  void handle_multi_touch(struct cyttsp_track_data *t, struct cyttsp *ts)
  129.  {
  130. -   u8 id;
  131. +   u8 id, count;
  132.     u8 i, loc;
  133.     void (*mt_sync_func)(struct input_dev *) = ts->platform_data->mt_sync;
  134.  
  135. @@ -657,23 +657,12 @@
  136.         if ((ts->act_trk[id] == CY_NTCH) || (t->cur_trk[id] != CY_NTCH))
  137.             continue;
  138.  
  139. -       input_report_abs(ts->input, ABS_MT_TRACKING_ID, id);
  140. -       input_report_abs(ts->input, ABS_MT_TOUCH_MAJOR, CY_NTCH);
  141. -       input_report_key(ts->input, BTN_TOUCH, CY_NTCH);
  142. -       input_report_abs(ts->input, ABS_MT_WIDTH_MAJOR, t->tool_width);
  143. -       input_report_abs(ts->input, ABS_MT_POSITION_X,
  144. -                   ts->prv_mt_pos[id][CY_XPOS]);
  145. -       input_report_abs(ts->input, ABS_MT_POSITION_Y,
  146. -                   ts->prv_mt_pos[id][CY_YPOS]);
  147. -       input_report_abs(ts->input, ABS_MT_PRESSURE, t->cur_mt_z[id]);
  148. -       if (mt_sync_func)
  149. -           mt_sync_func(ts->input);
  150.         ts->act_trk[id] = CY_NTCH;
  151.         ts->prv_mt_pos[id][CY_XPOS] = 0;
  152.         ts->prv_mt_pos[id][CY_YPOS] = 0;
  153.     }
  154.     /* set Multi-Touch current event signals */
  155. -   for (id = 0; id < CY_NUM_MT_TCH_ID; id++) {
  156. +   for (count = id = 0; id < CY_NUM_MT_TCH_ID; id++) {
  157.         if (t->cur_mt_tch[id] >= CY_NUM_TRK_ID)
  158.             continue;
  159.  
  160. @@ -681,7 +670,6 @@
  161.                         t->cur_mt_tch[id]);
  162.         input_report_abs(ts->input, ABS_MT_TOUCH_MAJOR,
  163.                         t->cur_mt_z[id]);
  164. -       input_report_key(ts->input, BTN_TOUCH, CY_TCH);
  165.         input_report_abs(ts->input, ABS_MT_WIDTH_MAJOR,
  166.                         t->tool_width);
  167.         input_report_abs(ts->input, ABS_MT_POSITION_X,
  168. @@ -693,10 +681,16 @@
  169.         if (mt_sync_func)
  170.             mt_sync_func(ts->input);
  171.  
  172. +       count++;
  173.         ts->act_trk[id] = CY_TCH;
  174.         ts->prv_mt_pos[id][CY_XPOS] = t->cur_mt_pos[id][CY_XPOS];
  175.         ts->prv_mt_pos[id][CY_YPOS] = t->cur_mt_pos[id][CY_YPOS];
  176.     }
  177. +   /* if no fingers were pressed, we need to output a MT sync so that the
  178. +    * userspace can identify when the last finger has been removed from
  179. +    * the device */
  180. +   if (!count)
  181. +       mt_sync_func(ts->input);
  182.     return;
  183.  no_track_id:
  184.  
  185. @@ -793,7 +787,6 @@
  186.         if (t->snd_trk[id] < CY_NUM_TRK_ID) {
  187.             input_report_abs(ts->input, ABS_MT_TOUCH_MAJOR,
  188.                     t->cur_mt_z[t->snd_trk[id]]);
  189. -           input_report_key(ts->input, BTN_TOUCH, CY_TCH);
  190.             input_report_abs(ts->input, ABS_MT_WIDTH_MAJOR,
  191.                     t->tool_width);
  192.             input_report_abs(ts->input, ABS_MT_POSITION_X,
  193. @@ -814,7 +807,6 @@
  194.             /* void out this touch */
  195.             input_report_abs(ts->input, ABS_MT_TOUCH_MAJOR,
  196.                             CY_NTCH);
  197. -           input_report_key(ts->input, BTN_TOUCH, CY_NTCH);
  198.             input_report_abs(ts->input, ABS_MT_WIDTH_MAJOR,
  199.                             t->tool_width);
  200.             input_report_abs(ts->input, ABS_MT_POSITION_X,
  201. @@ -2141,22 +2133,27 @@
  202.     set_bit(EV_SYN, input_device->evbit);
  203.     set_bit(EV_KEY, input_device->evbit);
  204.     set_bit(EV_ABS, input_device->evbit);
  205. -   set_bit(BTN_TOUCH, input_device->keybit);
  206. -   set_bit(BTN_2, input_device->keybit);
  207. +   if (ts->platform_data->use_st) {
  208. +       set_bit(BTN_TOUCH, input_device->keybit);
  209. +       set_bit(BTN_2, input_device->keybit);
  210. +   }
  211.     if (ts->platform_data->use_gestures)
  212.         set_bit(BTN_3, input_device->keybit);
  213.  
  214. -   input_set_abs_params(input_device, ABS_X, 0, ts->platform_data->maxx,
  215. -                0, 0);
  216. -   input_set_abs_params(input_device, ABS_Y, 0, ts->platform_data->maxy,
  217. -                0, 0);
  218. -   input_set_abs_params(input_device, ABS_TOOL_WIDTH, 0,
  219. -                CY_LARGE_TOOL_WIDTH, 0, 0);
  220. -   input_set_abs_params(input_device, ABS_PRESSURE, 0, CY_MAXZ, 0, 0);
  221. -   input_set_abs_params(input_device, ABS_HAT0X, 0,
  222. -                ts->platform_data->maxx, 0, 0);
  223. -   input_set_abs_params(input_device, ABS_HAT0Y, 0,
  224. -                ts->platform_data->maxy, 0, 0);
  225. +   if (ts->platform_data->use_st) {
  226. +       input_set_abs_params(input_device, ABS_X, 0,
  227. +               ts->platform_data->maxx, 0, 0);
  228. +       input_set_abs_params(input_device, ABS_Y, 0,
  229. +               ts->platform_data->maxy, 0, 0);
  230. +       input_set_abs_params(input_device, ABS_TOOL_WIDTH, 0,
  231. +               CY_LARGE_TOOL_WIDTH, 0, 0);
  232. +       input_set_abs_params(input_device, ABS_PRESSURE, 0, CY_MAXZ,
  233. +               0, 0);
  234. +       input_set_abs_params(input_device, ABS_HAT0X, 0,
  235. +               ts->platform_data->maxx, 0, 0);
  236. +       input_set_abs_params(input_device, ABS_HAT0Y, 0,
  237. +               ts->platform_data->maxy, 0, 0);
  238. +   }
  239.     if (ts->platform_data->use_gestures) {
  240.         input_set_abs_params(input_device, ABS_HAT1X, 0, CY_MAXZ,
  241.                      0, 0);
  242. diff -ruN a/4.1.B.0.431//kernel/drivers/usb/gadget/epautoconf.c b/4.1.B.0.479//kernel/drivers/usb/gadget/epautoconf.c
  243. --- a/4.1.B.0.431//kernel/drivers/usb/gadget/epautoconf.c   2012-05-25 19:07:11.000000000 +0900
  244. +++ b/4.1.B.0.479//kernel/drivers/usb/gadget/epautoconf.c   2012-06-25 19:47:11.000000000 +0900
  245. @@ -302,6 +302,7 @@
  246.  
  247.     list_for_each_entry (ep, &gadget->ep_list, ep_list) {
  248.         ep->driver_data = NULL;
  249. +       ep->maxpacket = 512;
  250.     }
  251.  #ifdef MANY_ENDPOINTS
  252.     in_epnum = 0;
  253. diff -ruN a/4.1.B.0.431//vendor/semc/hardware/felica/Android.mk b/4.1.B.0.479//vendor/semc/hardware/felica/Android.mk
  254. --- a/4.1.B.0.431//vendor/semc/hardware/felica/Android.mk   1970-01-01 09:00:00.000000000 +0900
  255. +++ b/4.1.B.0.479//vendor/semc/hardware/felica/Android.mk   2012-06-25 19:30:44.000000000 +0900
  256. @@ -0,0 +1,48 @@
  257. +ifeq (true, $(SEMC_CFG_FELICA_ENABLED))
  258. +
  259. +LOCAL_PATH:= $(call my-dir)
  260. +SAVED_LOCAL_PATH_FLC:= $(LOCAL_PATH)
  261. +
  262. +include $(CLEAR_VARS)
  263. +
  264. +# now the part that is actually built
  265. +
  266. +LOCAL_PATH_ABS_FLC := $(shell cd $(SAVED_LOCAL_PATH_FLC) && pwd)
  267. +
  268. +BUILD_ROOT_FLC := $(TARGET_OUT_INTERMEDIATES)/FELICA_OBJ
  269. +
  270. +BUILD_SUBDIRS_FLC := $(shell cd $(SAVED_LOCAL_PATH_FLC) && find . -type d)
  271. +BUILD_SRC_FLC := $(shell cd $(SAVED_LOCAL_PATH_FLC) && find . -name \*[ch])
  272. +BUILD_MK_FLC := $(shell cd $(SAVED_LOCAL_PATH_FLC) && find . -name Makefile)
  273. +
  274. +REL_SUBDIRS_FLC := $(addprefix $(SAVED_LOCAL_PATH_FLC)/, $(BUILD_SUBDIRS_FLC))
  275. +REL_SRC_FLC := $(addprefix $(SAVED_LOCAL_PATH_FLC)/, $(BUILD_SRC_FLC))
  276. +REL_MK_FLC := $(addprefix $(SAVED_LOCAL_PATH_FLC)/, $(BUILD_MK_FLC))
  277. +
  278. +$(BUILD_ROOT_FLC)/semc_felica.ko: $(PRODUCT_OUT)/kernel prep_flc
  279. +   @(cd $(BUILD_ROOT_FLC); $(MAKE) KERNEL_DIR=$(ANDROID_PRODUCT_OUT)/obj/KERNEL_OBJ -f Makefile)
  280. +
  281. +prep_flc: subdirs_flc src_flc mk_flc
  282. +
  283. +subdirs_flc: $(REL_SUBDIRS_FLC)
  284. +   @(for i in $(BUILD_SUBDIRS_FLC); do mkdir -p $(BUILD_ROOT_FLC)/$$i; done)
  285. +
  286. +src_flc: $(REL_SRC_FLC) subdirs_flc
  287. +   @(for i in $(BUILD_SRC_FLC); do test -e $(BUILD_ROOT_FLC)/$$i || ln -sf $(LOCAL_PATH_ABS_FLC)/$$i $(BUILD_ROOT_FLC)/$$i; done)
  288. +
  289. +mk_flc: $(REL_MK_FLC) subdirs_flc
  290. +   @(for i in $(BUILD_MK_FLC); do test -e $(BUILD_ROOT_FLC)/$$i || ln -sf $(LOCAL_PATH_ABS_FLC)/$$i $(BUILD_ROOT_FLC)/$$i; done)
  291. +
  292. +# copy the modules
  293. +
  294. +files := semc_felica.ko
  295. +
  296. +copy_to := $(addprefix $(TARGET_OUT)/lib/modules/,$(files))
  297. +copy_from := $(addprefix $(BUILD_ROOT_FLC)/,$(files))
  298. +
  299. +$(TARGET_OUT)/lib/modules/%.ko : $(BUILD_ROOT_FLC)/%.ko | $(ACP)
  300. +   $(transform-prebuilt-to-target)
  301. +
  302. +ALL_PREBUILT += $(copy_to)
  303. +
  304. +endif
  305. diff -ruN a/4.1.B.0.431//vendor/semc/hardware/felica/Makefile b/4.1.B.0.479//vendor/semc/hardware/felica/Makefile
  306. --- a/4.1.B.0.431//vendor/semc/hardware/felica/Makefile 1970-01-01 09:00:00.000000000 +0900
  307. +++ b/4.1.B.0.479//vendor/semc/hardware/felica/Makefile 2012-06-25 19:30:44.000000000 +0900
  308. @@ -0,0 +1,29 @@
  309. +#
  310. +# Makefile for FeliCa kernel module
  311. +#
  312. +# Copyright 2010 Sony Ericsson Mobile Communications Japan Inc.
  313. +# All rights, including trade secret rights, reserved.
  314. +#
  315. +
  316. +# environment variables
  317. +CROSS_COMPILE  := arm-eabi-
  318. +ARCH           := arm
  319. +PWD := $(shell pwd)
  320. +
  321. +obj-m = semc_felica.o
  322. +
  323. +semc_felica-objs = felica_master.o \
  324. +                   felica_uart.o felica_statemachine.o \
  325. +                   msm_uartdm.o felica_rxbuf.o felica_txbuf.o msm_uartmux.o \
  326. +                   msm_felica_cen.o \
  327. +                   felica_pon.o \
  328. +                   felica_rfs.o \
  329. +                   felica_int.o \
  330. +                   felica_rws.o
  331. +
  332. +all:
  333. +   $(MAKE) CROSS_COMPILE=$(CROSS_COMPILE) ARCH=$(ARCH) -C $(KERNEL_DIR) M=$(PWD) modules
  334. +
  335. +clean:
  336. +   $(MAKE) CROSS_COMPILE=$(CROSS_COMPILE) ARCH=$(ARCH) -C $(KERNEL_DIR) M=$(PWD) clean
  337. +
  338. diff -ruN a/4.1.B.0.431//vendor/semc/hardware/felica/felica_cen.h b/4.1.B.0.479//vendor/semc/hardware/felica/felica_cen.h
  339. --- a/4.1.B.0.431//vendor/semc/hardware/felica/felica_cen.h 1970-01-01 09:00:00.000000000 +0900
  340. +++ b/4.1.B.0.479//vendor/semc/hardware/felica/felica_cen.h 2012-06-25 19:30:44.000000000 +0900
  341. @@ -0,0 +1,24 @@
  342. +/* vendor/semc/hardware/felica/felica_cen.h
  343. + *
  344. + * Copyright (C) 2010 Sony Ericsson Mobile Communications AB.
  345. + *
  346. + * Author: Hiroaki Kuriyama <[email protected]>
  347. + *
  348. + * This program is free software; you can redistribute it and/or modify
  349. + * it under the terms of the GNU General Public License version 2, as
  350. + * published by the Free Software Foundation; either version 2
  351. + * of the License, or (at your option) any later version.
  352. + */
  353. +
  354. +#ifndef _FELICA_CEN_H
  355. +#define _FELICA_CEN_H
  356. +
  357. +
  358. +#define UDELAY_CEN_WRITE 100
  359. +
  360. +struct felica_cen_pfdata;
  361. +
  362. +int felica_cen_probe_func(struct felica_cen_pfdata *);
  363. +void felica_cen_remove_func(void);
  364. +
  365. +#endif
  366. diff -ruN a/4.1.B.0.431//vendor/semc/hardware/felica/felica_int.c b/4.1.B.0.479//vendor/semc/hardware/felica/felica_int.c
  367. --- a/4.1.B.0.431//vendor/semc/hardware/felica/felica_int.c 1970-01-01 09:00:00.000000000 +0900
  368. +++ b/4.1.B.0.479//vendor/semc/hardware/felica/felica_int.c 2012-06-25 19:30:44.000000000 +0900
  369. @@ -0,0 +1,212 @@
  370. +/* vendor/semc/hardware/felica/felica_int.c
  371. + *
  372. + * Copyright (C) 2010 Sony Ericsson Mobile Communications AB.
  373. + *
  374. + * Author: Hiroaki Kuriyama <[email protected]>
  375. + *
  376. + * This program is free software; you can redistribute it and/or modify
  377. + * it under the terms of the GNU General Public License version 2, as
  378. + * published by the Free Software Foundation; either version 2
  379. + * of the License, or (at your option) any later version.
  380. + */
  381. +
  382. +#include <linux/module.h>
  383. +#include <linux/kernel.h>
  384. +#include <linux/init.h>
  385. +#include <linux/types.h>
  386. +#include <linux/stddef.h>
  387. +#include <linux/mfd/pmic8058.h>
  388. +#include <linux/uaccess.h>
  389. +#include <linux/gpio.h>
  390. +#include <linux/interrupt.h>
  391. +#include <mach/irqs.h>
  392. +#include <linux/switch.h>
  393. +#include <linux/workqueue.h>
  394. +#include "semc_felica_ext.h"
  395. +#include "felica_int.h"
  396. +
  397. +#define PRT_NAME "felica int"
  398. +#define INT_LOW  0x0
  399. +#define INT_HIGH 0x1
  400. +#define DEFAULT_INT_STATE INT_HIGH
  401. +
  402. +struct felica_int_data {
  403. +   struct felica_int_pfdata    *pfdata;
  404. +   struct switch_dev       swdev;
  405. +   struct work_struct      work_int;
  406. +   spinlock_t          lock_int;
  407. +};
  408. +
  409. +static struct felica_int_data *flint;
  410. +
  411. +/**
  412. + * @brief   Interrupt handler of FeliCa INT controller
  413. + * @details This function executes;\n
  414. + *            # Disable INT interrupt\n
  415. + *            # Schedule work for FeliCa push (keventd_wq)
  416. + * @param   irq         : (unused)
  417. + * @param   dev         : (unused)
  418. + * @retval  IRQ_HANDLED : Success
  419. + * @note
  420. + */
  421. +static irqreturn_t felica_int_irq_handler(int irq, void *dev)
  422. +{
  423. +   pr_debug(PRT_NAME ": %s\n", __func__);
  424. +
  425. +   /* Disable INT interrupt */
  426. +   disable_irq_nosync(flint->pfdata->irq_int);
  427. +   /* Schedule work for FeliCa push (keventd_wq) */
  428. +   schedule_work(&flint->work_int);
  429. +
  430. +   return IRQ_HANDLED;
  431. +}
  432. +
  433. +/**
  434. + * @brief   Interrupt work description of FeliCa INT controller
  435. + * @details This function executes;\n
  436. + *            # Read INT GPIO\n
  437. + *            # Update value of the switch device\n
  438. + *            # Enable INT interrupt\n
  439. + * @param   work : (unused)
  440. + * @retval  N/A
  441. + * @note
  442. + */
  443. +static void felica_int_exec(struct work_struct *work)
  444. +{
  445. +   int state;
  446. +
  447. +   pr_debug(PRT_NAME ": %s\n", __func__);
  448. +
  449. +   /* Read INT GPIO */
  450. +   state = gpio_get_value_cansleep(flint->pfdata->gpio_int);
  451. +   if (INT_LOW == state || INT_HIGH == state) {
  452. +       /* Update value of the switch device */
  453. +       switch_set_state(&flint->swdev, state);
  454. +       pr_debug(PRT_NAME ":  INT state = %d\n", state);
  455. +       /* Enable INT interrupt */
  456. +       enable_irq(flint->pfdata->irq_int);
  457. +   } else
  458. +       pr_err(PRT_NAME ": Error. Cannot read INT GPIO.\n");
  459. +}
  460. +
  461. +/**
  462. + * @brief   Initialize FeliCa INT controller
  463. + * @details This function executes;\n
  464. + *            # Check INT platform data\n
  465. + *            # Alloc and init INT controller's data\n
  466. + *            # Init work of FeliCa push\n
  467. + *            # Request INT GPIO\n
  468. + *            # Request IRQ for INT GPIO\n
  469. + *            # Enable IRQ wake for INT GPIO\n
  470. + *            # Create INT switch device (felica_push)\n
  471. + *            # Set default state of the device
  472. + * @param   pfdata   : Pointer to INT platform data
  473. + * @retval  0        : Success
  474. + * @retval  Negative : Failure\n
  475. + *            -EINVAL = No platform data\n
  476. + *            -ENOMEM = No enough memory / Cannot create switch dev\n
  477. + *            -ENODEV = GPIO request failed\n
  478. + *            -EIO    = IRQ request failed / Enabling IRQ wake failed
  479. + */
  480. +int felica_int_probe_func(struct felica_int_pfdata *pfdata)
  481. +{
  482. +   int ret;
  483. +
  484. +   pr_debug(PRT_NAME ": %s\n", __func__);
  485. +
  486. +   /* Check INT platform data */
  487. +   if (!pfdata) {
  488. +       pr_err(PRT_NAME ": Error. No platform data for INT.\n");
  489. +       return -EINVAL;
  490. +   }
  491. +
  492. +   /* Alloc and init INT controller's data */
  493. +   flint = kzalloc(sizeof(struct felica_int_data), GFP_KERNEL);
  494. +   if (!flint) {
  495. +       pr_err(PRT_NAME ": Error. No enough mem for INT.\n");
  496. +       ret = -ENOMEM;
  497. +       goto err_alloc_int_data;
  498. +   }
  499. +   flint->pfdata = pfdata;
  500. +
  501. +   /* Init work of FeliCa push */
  502. +   INIT_WORK(&flint->work_int, felica_int_exec);
  503. +
  504. +   /* Request INT GPIO */
  505. +   ret = gpio_request(flint->pfdata->gpio_int, "felica_int");
  506. +   if (ret) {
  507. +       pr_err(PRT_NAME ": Error. INT GPIO request failed.\n");
  508. +       ret = -ENODEV;
  509. +       goto err_request_int_gpio;
  510. +   }
  511. +   ret = gpio_direction_input(flint->pfdata->gpio_int);
  512. +   if (ret) {
  513. +       pr_err(PRT_NAME ": Error. INT GPIO direction failed.\n");
  514. +       ret = -ENODEV;
  515. +       goto err_direction_int_gpio;
  516. +   }
  517. +
  518. +   /* Request IRQ for INT GPIO */
  519. +   ret = request_irq(flint->pfdata->irq_int, felica_int_irq_handler,
  520. +    IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, "felica_irq", NULL);
  521. +   if (ret) {
  522. +       pr_err(PRT_NAME ": Error. Request IRQ failed.\n");
  523. +       ret = -EIO;
  524. +       goto err_request_int_irq;
  525. +   }
  526. +
  527. +   /* Enable IRQ wake */
  528. +   ret = enable_irq_wake(flint->pfdata->irq_int);
  529. +   if (ret) {
  530. +       pr_err(PRT_NAME ": Error. Enabling IRQ wake failed.\n");
  531. +       ret = -EIO;
  532. +       goto err_enable_irq_wake;
  533. +   }
  534. +
  535. +   /* Create INT switch device (felica_push) */
  536. +   flint->swdev.name = "felica_push";
  537. +   if (switch_dev_register(&flint->swdev)) {
  538. +       pr_err(PRT_NAME ": Error. Cannot create switch dev\n");
  539. +       ret = -ENOMEM;
  540. +       goto err_create_switch_dev;
  541. +   }
  542. +
  543. +   /* Set dafault state of the device */
  544. +   switch_set_state(&flint->swdev, DEFAULT_INT_STATE);
  545. +
  546. +   return 0;
  547. +
  548. +err_create_switch_dev:
  549. +   disable_irq_wake(flint->pfdata->irq_int);
  550. +err_enable_irq_wake:
  551. +   free_irq(flint->pfdata->irq_int, NULL);
  552. +err_request_int_irq:
  553. +err_direction_int_gpio:
  554. +   gpio_free(flint->pfdata->gpio_int);
  555. +err_request_int_gpio:
  556. +   kfree(flint);
  557. +err_alloc_int_data:
  558. +   return ret;
  559. +}
  560. +
  561. +/**
  562. + * @brief   Terminate FeliCa INT controller
  563. + * @details This function executes;\n
  564. + *            # Unregister switch device (felica_push)\n
  565. + *            # Release IRQ for INT GPIO\n
  566. + *            # Release INT GPIO resource\n
  567. + *            # Release INT controller's data
  568. + * @param   N/A
  569. + * @retval  N/A
  570. + * @note
  571. + */
  572. +void felica_int_remove_func(void)
  573. +{
  574. +   pr_debug(PRT_NAME ": %s\n", __func__);
  575. +
  576. +   switch_dev_unregister(&flint->swdev);
  577. +   disable_irq_wake(flint->pfdata->irq_int);
  578. +   free_irq(flint->pfdata->irq_int, NULL);
  579. +   gpio_free(flint->pfdata->gpio_int);
  580. +   kfree(flint);
  581. +}
  582. diff -ruN a/4.1.B.0.431//vendor/semc/hardware/felica/felica_int.h b/4.1.B.0.479//vendor/semc/hardware/felica/felica_int.h
  583. --- a/4.1.B.0.431//vendor/semc/hardware/felica/felica_int.h 1970-01-01 09:00:00.000000000 +0900
  584. +++ b/4.1.B.0.479//vendor/semc/hardware/felica/felica_int.h 2012-06-25 19:30:44.000000000 +0900
  585. @@ -0,0 +1,21 @@
  586. +/* vendor/semc/hardware/felica/felica_int.h
  587. + *
  588. + * Copyright (C) 2010 Sony Ericsson Mobile Communications AB.
  589. + *
  590. + * Author: Hiroaki Kuriyama <[email protected]>
  591. + *
  592. + * This program is free software; you can redistribute it and/or modify
  593. + * it under the terms of the GNU General Public License version 2, as
  594. + * published by the Free Software Foundation; either version 2
  595. + * of the License, or (at your option) any later version.
  596. + */
  597. +
  598. +#ifndef _FELICA_INT_H
  599. +#define _FELICA_INT_H
  600. +
  601. +struct felica_int_pfdata;
  602. +
  603. +int felica_int_probe_func(struct felica_int_pfdata *);
  604. +void felica_int_remove_func(void);
  605. +
  606. +#endif
  607. diff -ruN a/4.1.B.0.431//vendor/semc/hardware/felica/felica_master.c b/4.1.B.0.479//vendor/semc/hardware/felica/felica_master.c
  608. --- a/4.1.B.0.431//vendor/semc/hardware/felica/felica_master.c  1970-01-01 09:00:00.000000000 +0900
  609. +++ b/4.1.B.0.479//vendor/semc/hardware/felica/felica_master.c  2012-06-25 19:30:44.000000000 +0900
  610. @@ -0,0 +1,226 @@
  611. +/* vendor/semc/hardware/felica/felica_master.c
  612. + *
  613. + * Copyright (C) 2010 Sony Ericsson Mobile Communications AB.
  614. + *
  615. + * Author: Hiroaki Kuriyama <[email protected]>
  616. + *
  617. + * This program is free software; you can redistribute it and/or modify
  618. + * it under the terms of the GNU General Public License version 2, as
  619. + * published by the Free Software Foundation; either version 2
  620. + * of the License, or (at your option) any later version.
  621. + */
  622. +
  623. +#include <linux/module.h>
  624. +#include <linux/kernel.h>
  625. +#include <linux/init.h>
  626. +#include <linux/types.h>
  627. +#include <linux/platform_device.h>
  628. +#include "semc_felica_ext.h"
  629. +#include "felica_uart.h"
  630. +#include "felica_cen.h"
  631. +#include "felica_pon.h"
  632. +#include "felica_rfs.h"
  633. +#include "felica_int.h"
  634. +#include "felica_rws.h"
  635. +
  636. +#define DRV_NAME "felica driver"
  637. +#define DRV_VERSION "0.2"
  638. +#define PRT_NAME "felica master"
  639. +
  640. +/**
  641. + * @brief   Probe function of FeliCa driver
  642. + * @details This function executes;\n
  643. + *            # Load platform data of FeliCa driver\n
  644. + *            # GPIO setting of MSM & PM\n
  645. + *            # Call initialization functions of each controller
  646. + * @param   pdev     : Pointer to data of FeliCa platform device
  647. + * @retval  0        : Success
  648. + * @retval  Negative : Failure
  649. + * @note
  650. + */
  651. +static int felica_probe(struct platform_device *pdev)
  652. +{
  653. +   int ret;
  654. +   struct felica_platform_data *flc_pfdata;
  655. +
  656. +   pr_debug(PRT_NAME ": %s\n", __func__);
  657. +
  658. +   /* Load platform data of FeliCa driver */
  659. +   flc_pfdata = pdev->dev.platform_data;
  660. +   if (NULL == flc_pfdata) {
  661. +       pr_err(PRT_NAME ": Error. No platform data.\n");
  662. +       ret = -EINVAL;
  663. +       goto err_get_platform_data;
  664. +   }
  665. +
  666. +   /* GPIO setting of MSM & PM */
  667. +   if (flc_pfdata->gpio_init) {
  668. +       ret = flc_pfdata->gpio_init();
  669. +       if (ret && -EBUSY != ret) {
  670. +           pr_err(PRT_NAME ": Error. GPIO init failed.\n");
  671. +           goto error_gpio_init;
  672. +       }
  673. +   }
  674. +
  675. +   /* Call initialization functions of each controller */
  676. +   ret = felica_uart_probe_func(&flc_pfdata->uart_pfdata);
  677. +   if (ret) {
  678. +       pr_err(PRT_NAME ": Error. UART probe failure.\n");
  679. +       goto err_uart_probe;
  680. +   }
  681. +
  682. +   ret = felica_cen_probe_func(&flc_pfdata->cen_pfdata);
  683. +   if (ret) {
  684. +       pr_err(PRT_NAME ": Error. CEN probe failure.\n");
  685. +       goto err_cen_probe;
  686. +   }
  687. +
  688. +   ret = felica_pon_probe_func(&flc_pfdata->pon_pfdata);
  689. +   if (ret) {
  690. +       pr_err(PRT_NAME ": Error. PON probe failure.\n");
  691. +       goto err_pon_probe;
  692. +   }
  693. +
  694. +   ret = felica_rfs_probe_func(&flc_pfdata->rfs_pfdata);
  695. +   if (ret) {
  696. +       pr_err(PRT_NAME ": Error. RFS probe failure.\n");
  697. +       goto err_rfs_probe;
  698. +   }
  699. +
  700. +   ret = felica_int_probe_func(&flc_pfdata->int_pfdata);
  701. +   if (ret) {
  702. +       pr_err(PRT_NAME ": Error. INT probe failure.\n");
  703. +       goto err_int_probe;
  704. +   }
  705. +
  706. +   ret = felica_rws_probe_func();
  707. +   if (ret) {
  708. +       pr_err(PRT_NAME ": Error. RWS probe failure.\n");
  709. +       goto err_rws_probe;
  710. +   }
  711. +
  712. +   return 0;
  713. +
  714. +/* Error handling */
  715. +err_rws_probe:
  716. +   felica_int_remove_func();
  717. +err_int_probe:
  718. +   felica_rfs_remove_func();
  719. +err_rfs_probe:
  720. +   felica_pon_remove_func();
  721. +err_pon_probe:
  722. +   felica_cen_remove_func();
  723. +err_cen_probe:
  724. +   felica_uart_remove_func();
  725. +err_uart_probe:
  726. +error_gpio_init:
  727. +err_get_platform_data:
  728. +   return ret;
  729. +}
  730. +
  731. +/**
  732. + * @brief   Remove function of FeliCa driver
  733. + * @details This function executes;\n
  734. + *            # Call termination functions of each controller
  735. + * @param   pdev : (unused)
  736. + * @retval  0    : Success
  737. + * @note
  738. + */
  739. +static int felica_remove(struct platform_device *pdev)
  740. +{
  741. +   pr_debug(PRT_NAME ": %s\n", __func__);
  742. +
  743. +   felica_rws_remove_func();
  744. +   felica_int_remove_func();
  745. +   felica_rfs_remove_func();
  746. +   felica_pon_remove_func();
  747. +   felica_cen_remove_func();
  748. +   felica_uart_remove_func();
  749. +
  750. +   return 0;
  751. +}
  752. +
  753. +/**
  754. + * @brief  Suspend function of FeliCa driver
  755. + * @param  pdev : (unused)
  756. + * @param  message
  757. + * @retval 0
  758. + * @note
  759. + */
  760. +static int felica_suspend(struct platform_device *pdev,
  761. +                   pm_message_t message)
  762. +{
  763. +   pr_debug(PRT_NAME ": %s\n", __func__);
  764. +
  765. +   return 0;
  766. +}
  767. +
  768. +/**
  769. + * @brief  Resume function of FeliCa driver
  770. + * @param  pdev : (unused)
  771. + * @retval 0
  772. + * @note
  773. + */
  774. +static int felica_resume(struct platform_device *pdev)
  775. +{
  776. +   pr_debug(PRT_NAME ": %s\n", __func__);
  777. +
  778. +   return 0;
  779. +}
  780. +
  781. +/**
  782. + * @brief Platform driver data structure of FeliCa driver
  783. + */
  784. +static struct platform_driver semc_felica_driver = {
  785. +   .probe      = felica_probe,
  786. +   .remove     = felica_remove,
  787. +   .suspend    = felica_suspend,
  788. +   .resume     = felica_resume,
  789. +   .driver     = {
  790. +       .name       = "semc_felica",
  791. +       .owner      = THIS_MODULE,
  792. +   },
  793. +};
  794. +
  795. +/**
  796. + * @brief   Init function of FeliCa driver
  797. + * @details This function executes;\n
  798. + *            # platform driver registration of FeliCa driver
  799. + * @param   N/A
  800. + * @retval  0        : Success
  801. + * @retval  Negative : Failure
  802. + * @note
  803. + */
  804. +static int __init felica_init(void)
  805. +{
  806. +   int ret;
  807. +
  808. +   pr_info(PRT_NAME ": FeliCa driver ver %s being loaded.\n",
  809. +                           DRV_VERSION);
  810. +
  811. +   ret = platform_driver_register(&semc_felica_driver);
  812. +   return ret;
  813. +}
  814. +
  815. +/**
  816. + * @brief   Exit function of FeliCa driver
  817. + * @details This function executes;\n
  818. + *            # platform driver unregistration of FeliCa driver
  819. + * @param   N/A
  820. + * @retval  N/A
  821. + * @note
  822. + */
  823. +static void __exit felica_exit(void)
  824. +{
  825. +   pr_info(PRT_NAME ": %s\n", __func__);
  826. +
  827. +   platform_driver_unregister(&semc_felica_driver);
  828. +}
  829. +
  830. +module_init(felica_init);
  831. +module_exit(felica_exit);
  832. +
  833. +MODULE_VERSION(DRV_VERSION);
  834. +MODULE_AUTHOR("SEMC");
  835. +MODULE_DESCRIPTION("FeliCa driver");
  836. +MODULE_LICENSE("GPL");
  837. diff -ruN a/4.1.B.0.431//vendor/semc/hardware/felica/felica_pon.c b/4.1.B.0.479//vendor/semc/hardware/felica/felica_pon.c
  838. --- a/4.1.B.0.431//vendor/semc/hardware/felica/felica_pon.c 1970-01-01 09:00:00.000000000 +0900
  839. +++ b/4.1.B.0.479//vendor/semc/hardware/felica/felica_pon.c 2012-06-25 19:30:44.000000000 +0900
  840. @@ -0,0 +1,258 @@
  841. +/* vendor/semc/hardware/felica/felica_pon.c
  842. + *
  843. + * Copyright (C) 2010 Sony Ericsson Mobile Communications AB.
  844. + *
  845. + * Author: Hiroaki Kuriyama <[email protected]>
  846. + *
  847. + * This program is free software; you can redistribute it and/or modify
  848. + * it under the terms of the GNU General Public License version 2, as
  849. + * published by the Free Software Foundation; either version 2
  850. + * of the License, or (at your option) any later version.
  851. + */
  852. +
  853. +#include <linux/module.h>
  854. +#include <linux/kernel.h>
  855. +#include <linux/init.h>
  856. +#include <linux/types.h>
  857. +#include <linux/stddef.h>
  858. +#include <linux/fs.h>
  859. +#include <linux/err.h>
  860. +#include <linux/miscdevice.h>
  861. +#include <linux/mfd/pmic8058.h>
  862. +#include <linux/delay.h>
  863. +#include <linux/uaccess.h>
  864. +#include <linux/gpio.h>
  865. +#include "semc_felica_ext.h"
  866. +#include "felica_pon.h"
  867. +#include "felica_rws.h"
  868. +
  869. +#define PRT_NAME "felica pon"
  870. +#define PON_LOW  0x00
  871. +#define PON_HIGH 0x01
  872. +
  873. +struct felica_pon_data {
  874. +   struct felica_pon_pfdata    *pfdata;
  875. +};
  876. +
  877. +static struct felica_pon_data *flpon;
  878. +
  879. +/**
  880. + * @brief   Open file operation of FeliCa PON controller
  881. + * @param   inode : (unused)
  882. + * @param   file  : (unused)
  883. + * @retval  0     : Success
  884. + * @note
  885. + */
  886. +static int felica_pon_open(struct inode *inode, struct file *file)
  887. +{
  888. +   pr_debug(PRT_NAME ": %s\n", __func__);
  889. +
  890. +   return 0;
  891. +}
  892. +
  893. +/**
  894. + * @brief   Close file operation of FeliCa PON controller
  895. + * @details This module is responsible for the following roles:\n
  896. + *            # Forcedly, write Low to PON GPIO\n
  897. + *            # Forcedly, turn off TVDD
  898. + * @param   inode    : (unused)
  899. + * @param   file     : (unused)
  900. + * @retval  0        : Success
  901. + * @note
  902. + */
  903. +static int felica_pon_release(struct inode *inode, struct file *file)
  904. +{
  905. +   pr_debug(PRT_NAME ": %s\n", __func__);
  906. +
  907. +   /* Forcedly, write Low to PON GPIO */
  908. +   gpio_set_value_cansleep(flpon->pfdata->gpio_pon, PON_LOW);
  909. +
  910. +   /* Forcedly, turn off TVDD */
  911. +   if (flpon->pfdata->tvdd_off)
  912. +       flpon->pfdata->tvdd_off();
  913. +
  914. +   return 0;
  915. +}
  916. +
  917. +/**
  918. + * @brief   Write file operation of FeliCa PON controller
  919. + * @details This function executes;\n
  920. + *            # Copy value from user space\n
  921. + *            # [When writing High,]\n
  922. + *            #   | Write High to PON GPIO\n
  923. + *            #   | [Params meet the condition,] turn on TVDD.\n
  924. + *            # [When writing Low,]\n
  925. + *            #   | Write Low to PON GPIO\n
  926. + *            #   | Forcedly, turn off TVDD.\n
  927. + * @param   file     : (unused)
  928. + * @param   buf      : Source of the written data
  929. + * @param   count    : Data length must be 1 Byte.
  930. + * @param   offset   : (unused)
  931. + * @retval  1        : Success
  932. + * @retval  Negative : Failure\n
  933. + *            -EINVAL = Invalid argument\n
  934. + *            -EFAULT = Cannot copy data from user space\n
  935. + *            -EIO    = Cannot control VREG
  936. + * @note
  937. + */
  938. +static ssize_t felica_pon_write(struct file *file, const char __user *buf,
  939. +                   size_t count, loff_t *offset)
  940. +{
  941. +   char kbuf;
  942. +   int ret;
  943. +
  944. +   pr_debug(PRT_NAME ": %s\n", __func__);
  945. +
  946. +   if (1 != count  || !buf) {
  947. +       pr_err(PRT_NAME ": Error. Invalid arg @PON write.\n");
  948. +       return -EINVAL;
  949. +   }
  950. +
  951. +   /* Copy value from user space */
  952. +   if (copy_from_user(&kbuf, buf, 1)) {
  953. +       pr_err(PRT_NAME ": Error. copy_from_user failure.\n");
  954. +       return -EFAULT;
  955. +   }
  956. +
  957. +   if (PON_HIGH == kbuf) {
  958. +       /* Write High to PON GPIO */
  959. +       gpio_set_value_cansleep(flpon->pfdata->gpio_pon, PON_HIGH);
  960. +       if (((PARAM_OFF == st_usbcon) && (PARAM_OFF == st_airplane))
  961. +                   || (PARAM_ON == ta_rwusb)) {
  962. +           pr_debug(PRT_NAME ": TVDD --> ON.\n");
  963. +           /* Turn on TVDD */
  964. +           if (flpon->pfdata->tvdd_on) {
  965. +               ret = flpon->pfdata->tvdd_on();
  966. +               if (ret) {
  967. +                   pr_err(PRT_NAME
  968. +                       ": Error. Cannot ctrl TVDD.\n");
  969. +                   return -EIO;
  970. +               }
  971. +           }
  972. +       } else {
  973. +           pr_debug(PRT_NAME ": TVDD == OFF.\n");
  974. +       }
  975. +   } else if (PON_LOW == kbuf) {
  976. +       /* Write LOW to PON GPIO */
  977. +       gpio_set_value_cansleep(flpon->pfdata->gpio_pon, PON_LOW);
  978. +       /* Turn off TVDD */
  979. +       if (flpon->pfdata->tvdd_off)
  980. +           flpon->pfdata->tvdd_off();
  981. +   } else {
  982. +       pr_err(PRT_NAME ": Error. Invalid val @PON write.\n");
  983. +       return -EINVAL;
  984. +   }
  985. +
  986. +   /* 1 byte write */
  987. +   return 1;
  988. +}
  989. +
  990. +/***************** PON FOPS ****************************/
  991. +static const struct file_operations felica_pon_fops = {
  992. +   .owner      = THIS_MODULE,
  993. +   .read       = NULL,
  994. +   .write      = felica_pon_write,
  995. +   .ioctl      = NULL,
  996. +   .open       = felica_pon_open,
  997. +   .release    = felica_pon_release,
  998. +   .fsync      = NULL,
  999. +};
  1000. +
  1001. +static struct miscdevice felica_pon_device = {
  1002. +   .minor = MISC_DYNAMIC_MINOR,
  1003. +   .name = "felica_pon",
  1004. +   .fops = &felica_pon_fops,
  1005. +};
  1006. +
  1007. +/**
  1008. + * @brief  Initilialize FeliCa PON controller
  1009. + * @details This function executes;\n
  1010. + *            # Check PON platform data\n
  1011. + *            # Alloc and init PON controller's data\n
  1012. + *            # Request PON GPIO\n
  1013. + *            # Disable TVDD vreg device\n
  1014. + *            # Create PON character device (/dev/felica_pon)
  1015. + * @param   pfdata   : Pointer to PON platform data
  1016. + * @retval  0        : Success
  1017. + * @retval  Negative : Initialization failed.\n
  1018. + *            -EINVAL = No platform data\n
  1019. + *            -ENODEV = Requesting GPIO failed / Getting TVDD dev failed\n
  1020. + *            -ENOMEM = No enough memory / Cannot create char dev
  1021. + *            -EIO    = Cannot control VREG
  1022. + * @note
  1023. + */
  1024. +int felica_pon_probe_func(struct felica_pon_pfdata *pfdata)
  1025. +{
  1026. +   int ret;
  1027. +
  1028. +   pr_debug(PRT_NAME ": %s\n", __func__);
  1029. +
  1030. +   /* Check PON platform data */
  1031. +   if (!pfdata) {
  1032. +       pr_err(PRT_NAME ": Error. No platform data for PON.\n");
  1033. +       return -EINVAL;
  1034. +   }
  1035. +
  1036. +   /* Alloc and init PON controller's data */
  1037. +   flpon = kzalloc(sizeof(struct felica_pon_data), GFP_KERNEL);
  1038. +   if (!flpon) {
  1039. +       pr_err(PRT_NAME ": Error. No enough mem for PON.\n");
  1040. +       ret = -ENOMEM;
  1041. +       goto err_alloc_pon_data;
  1042. +   }
  1043. +   flpon->pfdata = pfdata;
  1044. +
  1045. +   /* Request PON GPIO */
  1046. +   ret = gpio_request(flpon->pfdata->gpio_pon, "felica_pon");
  1047. +   if (ret) {
  1048. +       pr_err(PRT_NAME ": Error. PON GPIO request failed.\n");
  1049. +       ret = -ENODEV;
  1050. +       goto err_request_pon_gpio;
  1051. +   }
  1052. +   ret = gpio_direction_output(flpon->pfdata->gpio_pon, PON_LOW);
  1053. +   if (ret) {
  1054. +       pr_err(PRT_NAME ": Error. PON GPIO direction failed.\n");
  1055. +       ret = -ENODEV;
  1056. +       goto err_direction_pon_gpio;
  1057. +   }
  1058. +
  1059. +   /* Disable TVDD vreg device */
  1060. +   if (flpon->pfdata->tvdd_off)
  1061. +       flpon->pfdata->tvdd_off();
  1062. +
  1063. +   /* Create PON character device (/dev/felica_pon) */
  1064. +   if (misc_register(&felica_pon_device)) {
  1065. +       pr_err(PRT_NAME ": Error. Cannot register PON.\n");
  1066. +       ret = -ENOMEM;
  1067. +       goto err_create_pon_dev;
  1068. +   }
  1069. +
  1070. +   return 0;
  1071. +
  1072. +err_create_pon_dev:
  1073. +err_direction_pon_gpio:
  1074. +   gpio_free(flpon->pfdata->gpio_pon);
  1075. +err_request_pon_gpio:
  1076. +   kfree(flpon);
  1077. +err_alloc_pon_data:
  1078. +   return ret;
  1079. +}
  1080. +
  1081. +/**
  1082. + * @brief   Terminate FeliCa PON controller
  1083. + * @details This function executes;\n
  1084. + *            # Deregister PON character device (/dev/felica_pon)\n
  1085. + *            # Release PON GPIO resource\n
  1086. + *            # Release PON controller's data
  1087. + * @param   N/A
  1088. + * @retval  N/A
  1089. + * @note
  1090. + */
  1091. +void felica_pon_remove_func(void)
  1092. +{
  1093. +   pr_debug(PRT_NAME ": %s\n", __func__);
  1094. +
  1095. +   misc_deregister(&felica_pon_device);
  1096. +   gpio_free(flpon->pfdata->gpio_pon);
  1097. +   kfree(flpon);
  1098. +}
  1099. diff -ruN a/4.1.B.0.431//vendor/semc/hardware/felica/felica_pon.h b/4.1.B.0.479//vendor/semc/hardware/felica/felica_pon.h
  1100. --- a/4.1.B.0.431//vendor/semc/hardware/felica/felica_pon.h 1970-01-01 09:00:00.000000000 +0900
  1101. +++ b/4.1.B.0.479//vendor/semc/hardware/felica/felica_pon.h 2012-06-25 19:30:44.000000000 +0900
  1102. @@ -0,0 +1,21 @@
  1103. +/* vendor/semc/hardware/felica/felica_pon.h
  1104. + *
  1105. + * Copyright (C) 2010 Sony Ericsson Mobile Communications AB.
  1106. + *
  1107. + * Author: Hiroaki Kuriyama <[email protected]>
  1108. + *
  1109. + * This program is free software; you can redistribute it and/or modify
  1110. + * it under the terms of the GNU General Public License version 2, as
  1111. + * published by the Free Software Foundation; either version 2
  1112. + * of the License, or (at your option) any later version.
  1113. + */
  1114. +
  1115. +#ifndef _FELICA_PON_H
  1116. +#define _FELICA_PON_H
  1117. +
  1118. +struct felica_pon_pfdata;
  1119. +
  1120. +int felica_pon_probe_func(struct felica_pon_pfdata *);
  1121. +void felica_pon_remove_func(void);
  1122. +
  1123. +#endif
  1124. diff -ruN a/4.1.B.0.431//vendor/semc/hardware/felica/felica_rfs.c b/4.1.B.0.479//vendor/semc/hardware/felica/felica_rfs.c
  1125. --- a/4.1.B.0.431//vendor/semc/hardware/felica/felica_rfs.c 1970-01-01 09:00:00.000000000 +0900
  1126. +++ b/4.1.B.0.479//vendor/semc/hardware/felica/felica_rfs.c 2012-06-25 19:30:44.000000000 +0900
  1127. @@ -0,0 +1,216 @@
  1128. +/* vendor/semc/hardware/felica/felica_rfs.c
  1129. + *
  1130. + * Copyright (C) 2010 Sony Ericsson Mobile Communications AB.
  1131. + *
  1132. + * Author: Hiroaki Kuriyama <[email protected]>
  1133. + *
  1134. + * This program is free software; you can redistribute it and/or modify
  1135. + * it under the terms of the GNU General Public License version 2, as
  1136. + * published by the Free Software Foundation; either version 2
  1137. + * of the License, or (at your option) any later version.
  1138. + */
  1139. +
  1140. +#include <linux/module.h>
  1141. +#include <linux/kernel.h>
  1142. +#include <linux/init.h>
  1143. +#include <linux/types.h>
  1144. +#include <linux/stddef.h>
  1145. +#include <linux/fs.h>
  1146. +#include <linux/miscdevice.h>
  1147. +#include <linux/mfd/pmic8058.h>
  1148. +#include <linux/uaccess.h>
  1149. +#include <linux/gpio.h>
  1150. +#include "semc_felica_ext.h"
  1151. +#include "felica_rfs.h"
  1152. +
  1153. +#define PRT_NAME "felica rfs"
  1154. +#define RFS_GPIO_L 0
  1155. +#define RFS_GPIO_H 1
  1156. +#define RFS_VAL_L  0x00
  1157. +#define RFS_VAL_H  0x01
  1158. +
  1159. +struct felica_rfs_data {
  1160. +   struct felica_rfs_pfdata    *pfdata;
  1161. +};
  1162. +
  1163. +static struct felica_rfs_data *flrfs;
  1164. +
  1165. +/**
  1166. + * @brief   Open file operation of FeliCa RFS controller
  1167. + * @param   inode : (unused)
  1168. + * @param   file  : (unused)
  1169. + * @retval  0     : Success
  1170. + * @note
  1171. + */
  1172. +static int felica_rfs_open(struct inode *inode, struct file *file)
  1173. +{
  1174. +   pr_debug(PRT_NAME ": %s\n", __func__);
  1175. +
  1176. +   return 0;
  1177. +}
  1178. +
  1179. +/**
  1180. + * @brief   Close file operation of FeliCa RFS controller
  1181. + * @param   inode : (unused)
  1182. + * @param   file  : (unused)
  1183. + * @retval  0     : Success
  1184. + * @note
  1185. + */
  1186. +static int felica_rfs_release(struct inode *inode, struct file *file)
  1187. +{
  1188. +   pr_debug(PRT_NAME ": %s\n", __func__);
  1189. +
  1190. +   return 0;
  1191. +}
  1192. +
  1193. +/**
  1194. + * @brief   Read file operation of FeliCa RFS controller
  1195. + * @details This function executes;\n
  1196. + *            # Read RFS GPIO value\n
  1197. + *            # Copy the value to user space
  1198. + * @param   inode    : (unused)
  1199. + * @param   file     : (unused)
  1200. + * @retval  1        : Success
  1201. + * @retval  Negative : Failure\n
  1202. + *            -EINVAL = Invalid argument\n
  1203. + *            -EIO    = GPIO read error\n
  1204. + *            -EFAULT = Cannot copy data to user space
  1205. + * @note
  1206. + */
  1207. +static ssize_t felica_rfs_read(struct file *file, char __user *buf,
  1208. +                   size_t count, loff_t *offset)
  1209. +{
  1210. +   char kbuf;
  1211. +   int gpio_val;
  1212. +
  1213. +   pr_debug(PRT_NAME ": %s\n", __func__);
  1214. +
  1215. +   if (1 != count  || !buf) {
  1216. +       pr_err(PRT_NAME ": Error. Invalid arg @RFS read.\n");
  1217. +       return -EINVAL;
  1218. +   }
  1219. +
  1220. +   /* Read RFS GPIO value */
  1221. +   gpio_val = gpio_get_value_cansleep(flrfs->pfdata->gpio_rfs);
  1222. +   if (RFS_GPIO_L == gpio_val)
  1223. +       kbuf = RFS_VAL_H;
  1224. +   else if (RFS_GPIO_H == gpio_val)
  1225. +       kbuf = RFS_VAL_L;
  1226. +   else {
  1227. +       pr_err(PRT_NAME ": Error. Invalid GPIO value @RFS read.\n");
  1228. +       return -EIO;
  1229. +   }
  1230. +
  1231. +   /* Copy the value to user space */
  1232. +   if (copy_to_user(buf, &kbuf, 1)) {
  1233. +       pr_err(PRT_NAME ": Error. copy_to_user failure.\n");
  1234. +       return -EFAULT;
  1235. +   }
  1236. +
  1237. +   /* 1 byte read */
  1238. +   return 1;
  1239. +}
  1240. +
  1241. +/***************** RFS FOPS ****************************/
  1242. +static const struct file_operations felica_rfs_fops = {
  1243. +   .owner      = THIS_MODULE,
  1244. +   .read       = felica_rfs_read,
  1245. +   .write      = NULL,
  1246. +   .ioctl      = NULL,
  1247. +   .open       = felica_rfs_open,
  1248. +   .release    = felica_rfs_release,
  1249. +   .fsync      = NULL,
  1250. +};
  1251. +
  1252. +static struct miscdevice felica_rfs_device = {
  1253. +   .minor = MISC_DYNAMIC_MINOR,
  1254. +   .name = "felica_rfs",
  1255. +   .fops = &felica_rfs_fops,
  1256. +};
  1257. +
  1258. +/**
  1259. + * @brief  Initilialize FeliCa RFS controller
  1260. + * @details This function executes;\n
  1261. + *            # Check RFS platform data\n
  1262. + *            # Alloc and init RFS controller's data\n
  1263. + *            # Request RFS GPIO\n
  1264. + *            # Create RFS character device (/dev/felica_rfs)
  1265. + * @param   pfdata   : Pointer to RFS platform data
  1266. + * @retval  0        : Success
  1267. + * @retval  Negative : Initialization failed.\n
  1268. + *            -EINVAL = No platform data\n
  1269. + *            -ENODEV = Requesting GPIO failed\n
  1270. + *            -ENOMEM = No enough memory / Cannot create char dev
  1271. + * @note
  1272. + */
  1273. +int felica_rfs_probe_func(struct felica_rfs_pfdata *pfdata)
  1274. +{
  1275. +   int ret;
  1276. +
  1277. +   pr_debug(PRT_NAME ": %s\n", __func__);
  1278. +
  1279. +   /* Check RFS platform data */
  1280. +   if (!pfdata) {
  1281. +       pr_err(PRT_NAME ": Error. No platform data for RFS.\n");
  1282. +       return -EINVAL;
  1283. +   }
  1284. +
  1285. +   /* Alloc and init RFS controller's data */
  1286. +   flrfs = kzalloc(sizeof(struct felica_rfs_data), GFP_KERNEL);
  1287. +   if (!flrfs) {
  1288. +       pr_err(PRT_NAME ": Error. No enough mem for RFS.\n");
  1289. +       ret = -ENOMEM;
  1290. +       goto err_alloc_rfs_data;
  1291. +   }
  1292. +   flrfs->pfdata = pfdata;
  1293. +
  1294. +   /* Request RFS GPIO */
  1295. +   ret = gpio_request(flrfs->pfdata->gpio_rfs, "felica_rfs");
  1296. +   if (ret) {
  1297. +       pr_err(PRT_NAME ": Error. RFS GPIO request failed.\n");
  1298. +       ret = -ENODEV;
  1299. +       goto err_request_rfs_gpio;
  1300. +   }
  1301. +   ret = gpio_direction_input(flrfs->pfdata->gpio_rfs);
  1302. +   if (ret) {
  1303. +       pr_err(PRT_NAME ": Error. RFS GPIO direction failed.\n");
  1304. +       ret = -ENODEV;
  1305. +       goto err_direction_rfs_gpio;
  1306. +   }
  1307. +
  1308. +   /* Create RFS character device (/dev/felica_rfs) */
  1309. +   if (misc_register(&felica_rfs_device)) {
  1310. +       pr_err(PRT_NAME ": Error. Cannot register RFS.\n");
  1311. +       ret = -ENOMEM;
  1312. +       goto err_create_rfs_dev;
  1313. +   }
  1314. +
  1315. +   return 0;
  1316. +
  1317. +err_create_rfs_dev:
  1318. +err_direction_rfs_gpio:
  1319. +   gpio_free(flrfs->pfdata->gpio_rfs);
  1320. +err_request_rfs_gpio:
  1321. +   kfree(flrfs);
  1322. +err_alloc_rfs_data:
  1323. +   return ret;
  1324. +}
  1325. +
  1326. +/**
  1327. + * @brief   Terminate FeliCa RFS controller
  1328. + * @details This function executes;\n
  1329. + *            # Deregister RFS character device (/dev/felica_rfs)\n
  1330. + *            # Release RFS GPIO resource\n
  1331. + *            # Release RFS controller's data
  1332. + * @param   N/A
  1333. + * @retval  N/A
  1334. + * @note
  1335. + */
  1336. +void felica_rfs_remove_func(void)
  1337. +{
  1338. +   pr_debug(PRT_NAME ": %s\n", __func__);
  1339. +
  1340. +   misc_deregister(&felica_rfs_device);
  1341. +   gpio_free(flrfs->pfdata->gpio_rfs);
  1342. +   kfree(flrfs);
  1343. +}
  1344. diff -ruN a/4.1.B.0.431//vendor/semc/hardware/felica/felica_rfs.h b/4.1.B.0.479//vendor/semc/hardware/felica/felica_rfs.h
  1345. --- a/4.1.B.0.431//vendor/semc/hardware/felica/felica_rfs.h 1970-01-01 09:00:00.000000000 +0900
  1346. +++ b/4.1.B.0.479//vendor/semc/hardware/felica/felica_rfs.h 2012-06-25 19:30:44.000000000 +0900
  1347. @@ -0,0 +1,21 @@
  1348. +/* vendor/semc/hardware/felica/felica_rfs.h
  1349. + *
  1350. + * Copyright (C) 2010 Sony Ericsson Mobile Communications AB.
  1351. + *
  1352. + * Author: Hiroaki Kuriyama <[email protected]>
  1353. + *
  1354. + * This program is free software; you can redistribute it and/or modify
  1355. + * it under the terms of the GNU General Public License version 2, as
  1356. + * published by the Free Software Foundation; either version 2
  1357. + * of the License, or (at your option) any later version.
  1358. + */
  1359. +
  1360. +#ifndef _FELICA_RFS_H
  1361. +#define _FELICA_RFS_H
  1362. +
  1363. +struct felica_rfs_pfdata;
  1364. +
  1365. +int felica_rfs_probe_func(struct felica_rfs_pfdata *);
  1366. +void felica_rfs_remove_func(void);
  1367. +
  1368. +#endif
  1369. diff -ruN a/4.1.B.0.431//vendor/semc/hardware/felica/felica_rws.c b/4.1.B.0.479//vendor/semc/hardware/felica/felica_rws.c
  1370. --- a/4.1.B.0.431//vendor/semc/hardware/felica/felica_rws.c 1970-01-01 09:00:00.000000000 +0900
  1371. +++ b/4.1.B.0.479//vendor/semc/hardware/felica/felica_rws.c 2012-06-25 19:30:44.000000000 +0900
  1372. @@ -0,0 +1,190 @@
  1373. +/* vendor/semc/hardware/felica/felica_rws.c
  1374. + *
  1375. + * Copyright (C) 2010 Sony Ericsson Mobile Communications AB.
  1376. + *
  1377. + * Author: Hiroaki Kuriyama <[email protected]>
  1378. + *
  1379. + * This program is free software; you can redistribute it and/or modify
  1380. + * it under the terms of the GNU General Public License version 2, as
  1381. + * published by the Free Software Foundation; either version 2
  1382. + * of the License, or (at your option) any later version.
  1383. + */
  1384. +
  1385. +#include <linux/module.h>
  1386. +#include <linux/kernel.h>
  1387. +#include <linux/init.h>
  1388. +#include <linux/types.h>
  1389. +#include <linux/stddef.h>
  1390. +#include <linux/fs.h>
  1391. +#include <linux/miscdevice.h>
  1392. +#include <linux/uaccess.h>
  1393. +#include "felica_rws.h"
  1394. +
  1395. +#define PRT_NAME "felica rws"
  1396. +#define ONEBYTE  1
  1397. +#define RWS_LOW  0x0
  1398. +#define RWS_HIGH 0x1
  1399. +
  1400. +/* Module parameters for Reader/Writer mode */
  1401. +unsigned int st_usbcon;
  1402. +unsigned int st_airplane;
  1403. +unsigned int ta_rwusb;
  1404. +
  1405. +module_param(st_usbcon, uint, S_IRUGO | S_IWUSR);
  1406. +MODULE_PARM_DESC(st_usbcon, "USB status for FeliCa");
  1407. +module_param(st_airplane, uint, S_IRUGO | S_IWUSR);
  1408. +MODULE_PARM_DESC(st_airplane, "Airplane mode status for FeliCa");
  1409. +module_param(ta_rwusb, uint, S_IRUGO | S_IWUSR);
  1410. +MODULE_PARM_DESC(ta_rwusb, "FeliCa RW disabling for USB");
  1411. +
  1412. +/**
  1413. + * @brief   Open file operation of FeliCa RWS controller
  1414. + * @param   inode : (unused)
  1415. + * @param   file  : (unused)
  1416. + * @retval  0     : Success
  1417. + * @note
  1418. + */
  1419. +static int felica_rws_open(struct inode *inode, struct file *file)
  1420. +{
  1421. +   pr_debug(PRT_NAME ": %s\n", __func__);
  1422. +
  1423. +   return 0;
  1424. +}
  1425. +
  1426. +/**
  1427. + * @brief   Close file operation of FeliCa RWS controller
  1428. + * @param   inode : (unused)
  1429. + * @param   file  : (unused)
  1430. + * @retval  0     : Success
  1431. + * @note
  1432. + */
  1433. +static int felica_rws_release(struct inode *inode, struct file *file)
  1434. +{
  1435. +   pr_debug(PRT_NAME ": %s\n", __func__);
  1436. +
  1437. +   return 0;
  1438. +}
  1439. +
  1440. +/**
  1441. + * @brief   Read file operation of FeliCa RWS controller
  1442. + * @details This function executes;\n
  1443. + *            # Check R/W module parameters\n
  1444. + *            # Determine RWS value\n
  1445. + *            # Copy the value to user space
  1446. + * @param   file      : (unused)
  1447. + * @param   buf       : Destination of the read data
  1448. + * @param   count     : Data length must be 1
  1449. + * @param   offset    : (unused)
  1450. + * @retval  ONEBYTE(1): Success.
  1451. + * @retval  Negative  : Failure\n
  1452. + *            -EINVAL = Invalid argument\n
  1453. + *            -EIO    = Invalid module parameters\n
  1454. + *            -EFAULT = Cannot copy data to user space
  1455. + * @note
  1456. + */
  1457. +static ssize_t felica_rws_read(struct file *file, char __user *buf,
  1458. +                   size_t count, loff_t *offset)
  1459. +{
  1460. +   char kbuf;
  1461. +
  1462. +   pr_debug(PRT_NAME ": %s\n", __func__);
  1463. +
  1464. +   if (ONEBYTE != count  || !buf) {
  1465. +       pr_err(PRT_NAME ": Error. Invalid arg @RWS read.\n");
  1466. +       return -EINVAL;
  1467. +   }
  1468. +
  1469. +   pr_debug(PRT_NAME ": st_usbcon = 0x%x\n", st_usbcon);
  1470. +   pr_debug(PRT_NAME ": st_airplane = 0x%x\n", st_airplane);
  1471. +   pr_debug(PRT_NAME ": ta_rwusb = 0x%x\n", ta_rwusb);
  1472. +
  1473. +   /* Check R/W module parameters */
  1474. +   if (PARAM_OFF != st_usbcon && PARAM_ON != st_usbcon) {
  1475. +       pr_err(PRT_NAME ": Error. Invalid st_usbcon value.\n");
  1476. +       return -EIO;
  1477. +   }
  1478. +   if (PARAM_OFF != st_airplane && PARAM_ON != st_airplane) {
  1479. +       pr_err(PRT_NAME ": Error. Invalid st_airplane value.\n");
  1480. +       return -EIO;
  1481. +   }
  1482. +   if (PARAM_OFF != ta_rwusb && PARAM_ON != ta_rwusb) {
  1483. +       pr_err(PRT_NAME ": Error. Invalid ta_rwusb value.\n");
  1484. +       return -EIO;
  1485. +   }
  1486. +
  1487. +   /* Determine RWS value */
  1488. +   if ((PARAM_ON == st_usbcon || PARAM_ON == st_airplane)
  1489. +                   && PARAM_OFF == ta_rwusb)
  1490. +       kbuf = RWS_HIGH;
  1491. +   else
  1492. +       kbuf = RWS_LOW;
  1493. +
  1494. +   /* Copy the value to user space */
  1495. +   if (copy_to_user(buf, &kbuf, ONEBYTE)) {
  1496. +       pr_err(PRT_NAME ": Error. copy_to_user failure.\n");
  1497. +       return -EFAULT;
  1498. +   }
  1499. +
  1500. +   /* 1 byte read */
  1501. +   return ONEBYTE;
  1502. +}
  1503. +
  1504. +/***************** RWS FOPS ****************************/
  1505. +static const struct file_operations felica_rws_fops = {
  1506. +   .owner      = THIS_MODULE,
  1507. +   .read       = felica_rws_read,
  1508. +   .write      = NULL,
  1509. +   .ioctl      = NULL,
  1510. +   .open       = felica_rws_open,
  1511. +   .release    = felica_rws_release,
  1512. +};
  1513. +
  1514. +static struct miscdevice felica_rws_device = {
  1515. +   .minor = MISC_DYNAMIC_MINOR,
  1516. +   .name = "felica_rws",
  1517. +   .fops = &felica_rws_fops,
  1518. +};
  1519. +
  1520. +/**
  1521. + * @brief  Initilialize FeliCa RWS controller
  1522. + * @details This function executes;\n
  1523. + *            # Initialize R/W module parameters\n
  1524. + *            # Create RWS character device (/dev/felica_rws)
  1525. + * @param   N/A
  1526. + * @retval  0        : Success
  1527. + * @retval  Negative : Initialization failed.\n
  1528. + *            -ENOMEM = Cannot create char dev
  1529. + * @note
  1530. + */
  1531. +int felica_rws_probe_func(void)
  1532. +{
  1533. +   pr_debug(PRT_NAME ": %s\n", __func__);
  1534. +
  1535. +   /* Initialize R/W module parameters */
  1536. +   st_usbcon = PARAM_OFF;
  1537. +   st_airplane = PARAM_OFF;
  1538. +   ta_rwusb = PARAM_OFF;
  1539. +
  1540. +   /* Create RWS character device (/dev/felica_rws) */
  1541. +   if (misc_register(&felica_rws_device)) {
  1542. +       pr_err(PRT_NAME ": Error. Cannot register RWS.\n");
  1543. +       return -ENOMEM;
  1544. +   }
  1545. +
  1546. +   return 0;
  1547. +}
  1548. +
  1549. +/**
  1550. + * @brief   Terminate FeliCa RWS controller
  1551. + * @details This function executes;\n
  1552. + *            # Deregister RWS character device (/dev/felica_rws)\n
  1553. + * @param   N/A
  1554. + * @retval  N/A
  1555. + * @note
  1556. + */
  1557. +void felica_rws_remove_func(void)
  1558. +{
  1559. +   pr_debug(PRT_NAME ": %s\n", __func__);
  1560. +
  1561. +   misc_deregister(&felica_rws_device);
  1562. +}
  1563. diff -ruN a/4.1.B.0.431//vendor/semc/hardware/felica/felica_rws.h b/4.1.B.0.479//vendor/semc/hardware/felica/felica_rws.h
  1564. --- a/4.1.B.0.431//vendor/semc/hardware/felica/felica_rws.h 1970-01-01 09:00:00.000000000 +0900
  1565. +++ b/4.1.B.0.479//vendor/semc/hardware/felica/felica_rws.h 2012-06-25 19:30:44.000000000 +0900
  1566. @@ -0,0 +1,26 @@
  1567. +/* vendor/semc/hardware/felica/felica_rws.h
  1568. + *
  1569. + * Copyright (C) 2010 Sony Ericsson Mobile Communications AB.
  1570. + *
  1571. + * Author: Hiroaki Kuriyama <[email protected]>
  1572. + *
  1573. + * This program is free software; you can redistribute it and/or modify
  1574. + * it under the terms of the GNU General Public License version 2, as
  1575. + * published by the Free Software Foundation; either version 2
  1576. + * of the License, or (at your option) any later version.
  1577. + */
  1578. +
  1579. +#ifndef _FELICA_RWS_H
  1580. +#define _FELICA_RWS_H
  1581. +
  1582. +#define PARAM_OFF 0
  1583. +#define PARAM_ON  1
  1584. +
  1585. +extern unsigned int st_usbcon;
  1586. +extern unsigned int st_airplane;
  1587. +extern unsigned int ta_rwusb;
  1588. +
  1589. +int felica_rws_probe_func(void);
  1590. +void felica_rws_remove_func(void);
  1591. +
  1592. +#endif
  1593. diff -ruN a/4.1.B.0.431//vendor/semc/hardware/felica/felica_rxbuf.c b/4.1.B.0.479//vendor/semc/hardware/felica/felica_rxbuf.c
  1594. --- a/4.1.B.0.431//vendor/semc/hardware/felica/felica_rxbuf.c   1970-01-01 09:00:00.000000000 +0900
  1595. +++ b/4.1.B.0.479//vendor/semc/hardware/felica/felica_rxbuf.c   2012-06-25 19:30:44.000000000 +0900
  1596. @@ -0,0 +1,319 @@
  1597. +/* vendor/semc/hardware/felica/felica_rxbuf.c
  1598. + *
  1599. + * Copyright (C) 2010 Sony Ericsson Mobile Communications AB.
  1600. + *
  1601. + * Author: Hiroaki Kuriyama <[email protected]>
  1602. + *
  1603. + * This program is free software; you can redistribute it and/or modify
  1604. + * it under the terms of the GNU General Public License version 2, as
  1605. + * published by the Free Software Foundation; either version 2
  1606. + * of the License, or (at your option) any later version.
  1607. + */
  1608. +
  1609. +#include <linux/module.h>
  1610. +#include <linux/kernel.h>
  1611. +#include <linux/init.h>
  1612. +#include <linux/types.h>
  1613. +#include <linux/stddef.h>
  1614. +#include <linux/dma-mapping.h>
  1615. +#include <linux/dmapool.h>
  1616. +#include <linux/uaccess.h>
  1617. +#include "felica_rxbuf.h"
  1618. +
  1619. +#define PRT_NAME "rxbuf"
  1620. +
  1621. +/* DEBUG_RXBUF_DUMP : 0 = without dump, 1 = with dump */
  1622. +#define DEBUG_RXBUF_DUMP 0
  1623. +#if DEBUG_RXBUF_DUMP
  1624. +#include <linux/string.h>
  1625. +#endif
  1626. +
  1627. +struct rxbuf_slot {
  1628. +   int head;
  1629. +   int tail;
  1630. +   char    *buf;
  1631. +   dma_addr_t dmabase;
  1632. +};
  1633. +
  1634. +struct rxbuf_all {
  1635. +   int wp;
  1636. +   int rp;
  1637. +   struct rxbuf_slot slot[RXBUF_N];
  1638. +   int count;
  1639. +   enum {no, yes} fulfill;
  1640. +   struct dma_pool *dmapool;
  1641. +};
  1642. +
  1643. +static struct rxbuf_all rxbuf;
  1644. +
  1645. +#if DEBUG_RXBUF_DUMP
  1646. +static char dump[RXBUF_M * RXBUF_N];
  1647. +#endif
  1648. +
  1649. +/**
  1650. + * @brief  Clear RX buffer
  1651. + * @param  N/A
  1652. + * @retval N/A
  1653. + * @note
  1654. + */
  1655. +void felica_rxbuf_clear(void)
  1656. +{
  1657. +   int i;
  1658. +
  1659. +   pr_debug(PRT_NAME ": %s\n", __func__);
  1660. +
  1661. +   rxbuf.wp = 0;
  1662. +   rxbuf.rp = 0;
  1663. +   for (i = 0; i < RXBUF_N; i++) {
  1664. +       rxbuf.slot[i].head = 0;
  1665. +       rxbuf.slot[i].tail = 0;
  1666. +   }
  1667. +   rxbuf.count = 0;
  1668. +   rxbuf.fulfill = no;
  1669. +}
  1670. +
  1671. +/**
  1672. + * @brief  Count the number of the stored data in RX buffer
  1673. + * @param  N/A
  1674. + * @retval 0/Positive : Success. the number of the stored data
  1675. + * @retval Negative   : Failure\n
  1676. + *           -ENODEV = RX buffer not initialized
  1677. + * @note
  1678. + */
  1679. +int felica_rxbuf_count(void)
  1680. +{
  1681. +   pr_debug(PRT_NAME ": %s\n", __func__);
  1682. +
  1683. +   if (!rxbuf.dmapool) {
  1684. +       pr_err(PRT_NAME ": Error. RX buf not initialized.\n");
  1685. +       return -ENODEV;
  1686. +   }
  1687. +
  1688. +   return rxbuf.count;
  1689. +}
  1690. +
  1691. +/**
  1692. + * @brief  Copy the stored data to User space buffer
  1693. + * @param  buf : Pointer to User space buffer
  1694. + * @param  len : Date length to copy
  1695. + * @retval Positive : Number of the data copied successfully.
  1696. + * @retval 0 : No data to copy
  1697. + * @retval Negative : Failure.\n
  1698. + *           -EINVAL = Invalid arguments\n
  1699. + *           -ENODEV = RX buffer not initialized\n
  1700. + *           -EFAULT = Data copy error
  1701. + */
  1702. +int felica_rxbuf_gets(char __user *buf, int len)
  1703. +{
  1704. +   int ret;
  1705. +   int cnt = 0;
  1706. +   int rest, srest;
  1707. +   int cpnum;
  1708. +
  1709. +#if DEBUG_RXBUF_DUMP
  1710. +   int i;
  1711. +#endif
  1712. +
  1713. +   pr_debug(PRT_NAME ": %s\n", __func__);
  1714. +
  1715. +   if ((0 >= len) || (NULL == buf)) {
  1716. +       pr_err(PRT_NAME ": Error. Invalid argument.\n");
  1717. +       return -EINVAL;
  1718. +   }
  1719. +   if (!rxbuf.dmapool) {
  1720. +       pr_err(PRT_NAME ": Error. RX buf not initialized.\n");
  1721. +       return -ENODEV;
  1722. +   }
  1723. +
  1724. +   if (0 == rxbuf.count)
  1725. +       return 0;
  1726. +
  1727. +   while (1) {
  1728. +       rest = len - cnt;
  1729. +       if (0 == rest)
  1730. +           break;
  1731. +       srest = rxbuf.slot[rxbuf.rp].head - rxbuf.slot[rxbuf.rp].tail;
  1732. +       cpnum = (rest < srest) ? rest : srest ;
  1733. +       ret = copy_to_user(buf + cnt, rxbuf.slot[rxbuf.rp].buf
  1734. +                   + rxbuf.slot[rxbuf.rp].tail, cpnum);
  1735. +       if (ret) {
  1736. +           pr_err(PRT_NAME ": Error. copy_to_user failure.\n");
  1737. +           return -EFAULT;
  1738. +       }
  1739. +
  1740. +#if DEBUG_RXBUF_DUMP
  1741. +       memcpy(dump + cnt, rxbuf.slot[rxbuf.rp].buf
  1742. +                   + rxbuf.slot[rxbuf.rp].tail, cpnum);
  1743. +#endif
  1744. +
  1745. +       rxbuf.slot[rxbuf.rp].tail += cpnum;
  1746. +       cnt += cpnum;
  1747. +       if (rxbuf.slot[rxbuf.rp].tail == rxbuf.slot[rxbuf.rp].head) {
  1748. +           rxbuf.slot[rxbuf.rp].tail = 0;
  1749. +           rxbuf.slot[rxbuf.rp].head = 0;
  1750. +           rxbuf.rp++;
  1751. +           rxbuf.rp %= RXBUF_N;
  1752. +           rxbuf.fulfill = no;
  1753. +       }
  1754. +       if (rxbuf.rp == rxbuf.wp)
  1755. +           break;
  1756. +   }
  1757. +   rxbuf.count -= cnt;
  1758. +
  1759. +#if DEBUG_RXBUF_DUMP
  1760. +   printk("RXgets dump: ");
  1761. +   for (i = 0; i < cnt; i++)
  1762. +       printk("%02x ", dump[i]);
  1763. +   printk("\n");
  1764. +#endif
  1765. +
  1766. +   return cnt;
  1767. +}
  1768. +
  1769. +/**
  1770. + * @brief  Return DMA address pointer to push data
  1771. + * @param  N/A
  1772. + * @retval Valid-address : DMA address to push
  1773. + * @retval 0 : No space to push
  1774. + */
  1775. +dma_addr_t felica_rxbuf_push_pointer(void)
  1776. +{
  1777. +   pr_debug(PRT_NAME ": %s\n", __func__);
  1778. +
  1779. +   if (yes == rxbuf.fulfill || !rxbuf.dmapool)
  1780. +       return 0;
  1781. +
  1782. +   return rxbuf.slot[rxbuf.wp].dmabase;
  1783. +}
  1784. +
  1785. +/**
  1786. + * @brief  Return data length possible to push
  1787. + * @param  N/A
  1788. + * @retval Positive : Data length of the space to push
  1789. + * @retval 0        : No space to push
  1790. + * @retval Negative : Failure\n
  1791. + *           -ENODEV = RX buffer not initialized
  1792. + * @note
  1793. + */
  1794. +int felica_rxbuf_push_length(void)
  1795. +{
  1796. +   pr_debug(PRT_NAME ": %s\n", __func__);
  1797. +
  1798. +   if (!rxbuf.dmapool) {
  1799. +       pr_err(PRT_NAME ": Error. RX buf not initialized.\n");
  1800. +       return -ENODEV;
  1801. +   }
  1802. +
  1803. +   if (yes == rxbuf.fulfill)
  1804. +       return 0;
  1805. +
  1806. +   return RXBUF_M;
  1807. +}
  1808. +
  1809. +/**
  1810. + * @brief  Update RX buffer status according to the pushed data.
  1811. + * @param  len : Data length already pushed
  1812. + * @retval 0 : Success
  1813. + * @retval Negative : Failure\n
  1814. + *           -EIO    = Invalid arguments\n
  1815. + *           -ENODEV = RX buffer not initialized.\n
  1816. + *           -EFAULT = RX buf is already fulfilled.
  1817. + * @note
  1818. + */
  1819. +int felica_rxbuf_push_status_update(int len)
  1820. +{
  1821. +   pr_debug(PRT_NAME ": %s\n", __func__);
  1822. +
  1823. +   if ((0 >= len) || (RXBUF_M < len)) {
  1824. +       pr_err(PRT_NAME ": Error. Invalid arg for push status.\n");
  1825. +       return -EINVAL;
  1826. +   }
  1827. +   if (!rxbuf.dmapool) {
  1828. +       pr_err(PRT_NAME ": Error. RX buf not initialized.\n");
  1829. +       return -ENODEV;
  1830. +   }
  1831. +
  1832. +   if (yes == rxbuf.fulfill) {
  1833. +       pr_err(PRT_NAME ": Error. RX buf is already fulfilled.\n");
  1834. +       return -EFAULT;
  1835. +   }
  1836. +
  1837. +   rxbuf.slot[rxbuf.wp].head = len;
  1838. +   rxbuf.wp++;
  1839. +   rxbuf.wp %= RXBUF_N;
  1840. +   if (rxbuf.wp == rxbuf.rp)
  1841. +       rxbuf.fulfill = yes;
  1842. +   rxbuf.count += len;
  1843. +
  1844. +   return 0;
  1845. +}
  1846. +
  1847. +/**
  1848. + * @brief  Initialize & alloc RX buffer
  1849. + * @details This function executes;\n
  1850. + *          # Create DMA pool\n
  1851. + *          # Alloc RX buffer\n
  1852. + *          # Call RX buffer clear
  1853. + * @param  N/A
  1854. + * @retval 0 : Success
  1855. + * @retval -ENOMEM : Error, no enough memory.
  1856. + * @note
  1857. + */
  1858. +int felica_rxbuf_init(void)
  1859. +{
  1860. +   int i;
  1861. +
  1862. +   pr_debug(PRT_NAME ": %s\n", __func__);
  1863. +
  1864. +   rxbuf.dmapool = dma_pool_create(DMAPOOL_NAME, NULL, DMAPOOL_SIZE,
  1865. +                   DMAPOOL_ALIGN, DMAPOOL_ALIGN * RXBUF_N);
  1866. +   if (!rxbuf.dmapool) {
  1867. +       pr_err(PRT_NAME ": Error. Cannot create DMA pool for RXbuf.");
  1868. +       return -ENOMEM;
  1869. +   }
  1870. +   for (i = 0; i < RXBUF_N; i++) {
  1871. +       rxbuf.slot[i].buf = dma_pool_alloc(rxbuf.dmapool, GFP_KERNEL,
  1872. +                       &rxbuf.slot[i].dmabase);
  1873. +       if (!rxbuf.slot[i].buf) {
  1874. +           pr_err(PRT_NAME
  1875. +               ": Error. No enough mem for RXbuf.\n");
  1876. +           goto err_alloc_rx_buf;
  1877. +       }
  1878. +   }
  1879. +
  1880. +   felica_rxbuf_clear();
  1881. +
  1882. +   return 0;
  1883. +
  1884. +err_alloc_rx_buf:
  1885. +   for (i--; i >= 0; i--) {
  1886. +       dma_pool_free(rxbuf.dmapool, rxbuf.slot[i].buf,
  1887. +                   rxbuf.slot[i].dmabase);
  1888. +   }
  1889. +   dma_pool_destroy(rxbuf.dmapool);
  1890. +   rxbuf.dmapool = NULL;
  1891. +   return -ENOMEM;
  1892. +}
  1893. +
  1894. +/**
  1895. + * @brief  Release RX buffer
  1896. + * @details This function executes;\n
  1897. + *          # Release RX buffer\n
  1898. + *          # Destroy DMA pool
  1899. + * @param  N/A
  1900. + * @retval N/A
  1901. + * @note
  1902. + */
  1903. +void felica_rxbuf_exit(void)
  1904. +{
  1905. +   int i;
  1906. +
  1907. +   pr_debug(PRT_NAME ": %s\n", __func__);
  1908. +
  1909. +   for (i = 0; i < RXBUF_N; i++) {
  1910. +       dma_pool_free(rxbuf.dmapool, rxbuf.slot[i].buf,
  1911. +                   rxbuf.slot[i].dmabase);
  1912. +   }
  1913. +   dma_pool_destroy(rxbuf.dmapool);
  1914. +   rxbuf.dmapool = NULL;
  1915. +}
  1916. diff -ruN a/4.1.B.0.431//vendor/semc/hardware/felica/felica_rxbuf.h b/4.1.B.0.479//vendor/semc/hardware/felica/felica_rxbuf.h
  1917. --- a/4.1.B.0.431//vendor/semc/hardware/felica/felica_rxbuf.h   1970-01-01 09:00:00.000000000 +0900
  1918. +++ b/4.1.B.0.479//vendor/semc/hardware/felica/felica_rxbuf.h   2012-06-25 19:30:44.000000000 +0900
  1919. @@ -0,0 +1,33 @@
  1920. +/* vendor/semc/hardware/felica/felica_rxbuf.h
  1921. + *
  1922. + * Copyright (C) 2010 Sony Ericsson Mobile Communications AB.
  1923. + *
  1924. + * Author: Hiroaki Kuriyama <[email protected]>
  1925. + *
  1926. + * This program is free software; you can redistribute it and/or modify
  1927. + * it under the terms of the GNU General Public License version 2, as
  1928. + * published by the Free Software Foundation; either version 2
  1929. + * of the License, or (at your option) any later version.
  1930. + */
  1931. +
  1932. +#ifndef _FELICA_RXBUF_H
  1933. +#define _FELICA_RXBUF_H
  1934. +
  1935. +#define RXBUF_M    272
  1936. +#define RXBUF_N    128
  1937. +
  1938. +#define DMAPOOL_NAME "felica_rxbuf"
  1939. +#define DMAPOOL_SIZE  RXBUF_M
  1940. +/* DMAPOOL_ALIGN must be ">=DMAPOOL_SIZE" and pow of 2 */
  1941. +#define DMAPOOL_ALIGN 512
  1942. +
  1943. +int felica_rxbuf_init(void);
  1944. +void felica_rxbuf_exit(void);
  1945. +void felica_rxbuf_clear(void);
  1946. +int felica_rxbuf_count(void);
  1947. +int felica_rxbuf_gets(char __user *, int);
  1948. +dma_addr_t felica_rxbuf_push_pointer(void);
  1949. +int felica_rxbuf_push_length(void);
  1950. +int felica_rxbuf_push_status_update(int);
  1951. +
  1952. +#endif
  1953. diff -ruN a/4.1.B.0.431//vendor/semc/hardware/felica/felica_statemachine.c b/4.1.B.0.479//vendor/semc/hardware/felica/felica_statemachine.c
  1954. --- a/4.1.B.0.431//vendor/semc/hardware/felica/felica_statemachine.c    1970-01-01 09:00:00.000000000 +0900
  1955. +++ b/4.1.B.0.479//vendor/semc/hardware/felica/felica_statemachine.c    2012-06-25 19:30:44.000000000 +0900
  1956. @@ -0,0 +1,183 @@
  1957. +/* vendor/semc/hardware/felica/felica_statemachine.c
  1958. + *
  1959. + * Copyright (C) 2010 Sony Ericsson Mobile Communications AB.
  1960. + *
  1961. + * Author: Hiroaki Kuriyama <[email protected]>
  1962. + *
  1963. + * This program is free software; you can redistribute it and/or modify
  1964. + * it under the terms of the GNU General Public License version 2, as
  1965. + * published by the Free Software Foundation; either version 2
  1966. + * of the License, or (at your option) any later version.
  1967. + */
  1968. +
  1969. +#include <linux/kernel.h>
  1970. +#include <linux/stddef.h>
  1971. +#include <linux/semaphore.h>
  1972. +#include "felica_statemachine.h"
  1973. +#include "felica_statemachine_userdata.h"
  1974. +
  1975. +#define PRT_NAME "flc_statemachine"
  1976. +#define BEFORE_INIT  (-1)
  1977. +#define INIT_STATE   (0)
  1978. +#define NO_EVENT_REQ (-1)
  1979. +
  1980. +static int state = BEFORE_INIT;
  1981. +static struct event_struct next_evset;
  1982. +static struct semaphore sem_transition;
  1983. +
  1984. +/**
  1985. + * @brief  Request next event during action
  1986. + * @param  evset : Requested event and its data
  1987. + * @retval 0 : Success.
  1988. + * @note
  1989. + */
  1990. +int felica_request_nextevent(struct event_struct evset)
  1991. +{
  1992. +   pr_debug(PRT_NAME ": %s\n", __func__);
  1993. +
  1994. +   next_evset = evset;
  1995. +
  1996. +   return 0;
  1997. +}
  1998. +
  1999. +/**
  2000. + * @brief   Core of State-machine event handler
  2001. + * @details This function executes;\n
  2002. + *          # Check the event number\n
  2003. + *          # Check the state number\n
  2004. + *          # Init request of next event\n
  2005. + *          # Dispatch event according to state\n
  2006. + *          # Execute the corresponding function\n
  2007. + *          # [If action succeeded,] go to the next state\n
  2008. + *          # [If action succeeded and the next event is requested,]
  2009. + *          # call this event handler recursively.\n
  2010. + *          # Return result
  2011. + * @param   evset : Requested event and its data
  2012. + * @retval  .retval : Return value of the last action\n
  2013. + *            0/Positive : Action succeeded.\n
  2014. + *            Negative   : Action failed.\n
  2015. + *              STATEMACHINE_ERROR(<0) = Statemachine handling error\n
  2016. + *              Others = Failure during the action is executed.
  2017. + * @retval  .ev : Event during the last action
  2018. + * @retval  .state : State during the last action
  2019. + * @note
  2020. + */
  2021. +static struct result_struct __felica_event_handle(struct event_struct evset)
  2022. +{
  2023. +   struct result_struct result;
  2024. +   struct transition_struct *t;
  2025. +
  2026. +   pr_debug(PRT_NAME ": %s (ev#%d/st#%d)\n", __func__, evset.ev, state);
  2027. +
  2028. +   result.ev = evset.ev;
  2029. +   result.state = state;
  2030. +
  2031. +   /* Check the event number */
  2032. +   if ((0 > evset.ev) || (__end_of_event <= evset.ev)) {
  2033. +       pr_err(PRT_NAME ": Error. Invalid Event number.\n");
  2034. +       result.retval = STATEMACHINE_ERROR;
  2035. +       return result;
  2036. +   }
  2037. +
  2038. +   /* Check the state number */
  2039. +   if ((0 > state) || (__end_of_state <= state)) {
  2040. +       pr_err(PRT_NAME ": Error. Invalid State number.\n");
  2041. +       result.retval = STATEMACHINE_ERROR;
  2042. +       return result;
  2043. +   }
  2044. +
  2045. +   /* Init next event */
  2046. +   next_evset.ev = NO_EVENT_REQ;
  2047. +   next_evset.evdata = NULL;
  2048. +
  2049. +   /* Dispatch event-state */
  2050. +   t = &tran[state][evset.ev];
  2051. +   if ((NULL == t->action) ||
  2052. +       (0 > t->nextstate) || (__end_of_state <= t->nextstate)) {
  2053. +       pr_err(PRT_NAME ": Error. Invalid transition defined.\n");
  2054. +       result.retval = STATEMACHINE_ERROR;
  2055. +       return result;
  2056. +   }
  2057. +
  2058. +   /* Execute action */
  2059. +   result.retval = (t->action)(evset.evdata);
  2060. +
  2061. +   if (0 > result.retval)
  2062. +       return result;
  2063. +
  2064. +   /* Change state */
  2065. +   pr_debug(PRT_NAME ": State change #%d -> #%d\n",
  2066. +                       state, t->nextstate);
  2067. +   state = t->nextstate;
  2068. +
  2069. +   /* Execute next event recursively, if exists. */
  2070. +   if (NO_EVENT_REQ != next_evset.ev)
  2071. +       result = __felica_event_handle(next_evset);
  2072. +
  2073. +   return result;
  2074. +}
  2075. +
  2076. +/**
  2077. + * @brief   State-machine event handler
  2078. + * @details This function executes;\n
  2079. + *          # Down semaphore\n
  2080. + *          # Call __felica_event_handle\n
  2081. + *          # Up semaphore
  2082. + *          # Return result
  2083. + * @param   evset : Requested event and its data
  2084. + * @retval  .retval : Return value of the last action\n
  2085. + * @retval  .ev : Event of the last action
  2086. + * @retval  .state : State of the last action
  2087. + * @note
  2088. + */
  2089. +struct result_struct felica_event_handle(struct event_struct evset)
  2090. +{
  2091. +   struct result_struct result;
  2092. +
  2093. +   pr_debug(PRT_NAME ": %s (ev#%d)\n", __func__, evset.ev);
  2094. +
  2095. +   down(&sem_transition);
  2096. +
  2097. +   result = __felica_event_handle(evset);
  2098. +
  2099. +   up(&sem_transition);
  2100. +
  2101. +   return result;
  2102. +}
  2103. +
  2104. +/**
  2105. + * @brief   Initialization of statemachine
  2106. + * @details This function executes;\n
  2107. + *          # Init the semaphore\n
  2108. + *          # Set the state to Default
  2109. + * @param   N/A
  2110. + * @retval  0 : Success
  2111. + * @note
  2112. + */
  2113. +int felica_statemachine_init(void)
  2114. +{
  2115. +   pr_debug(PRT_NAME ": %s\n", __func__);
  2116. +
  2117. +   /* Init semaphore */
  2118. +   init_MUTEX(&sem_transition);
  2119. +
  2120. +   /* Start from the default state */
  2121. +   state = INIT_STATE;
  2122. +
  2123. +   return 0;
  2124. +}
  2125. +
  2126. +/**
  2127. + * @brief   Exit function of statemachine
  2128. + * @details This function executes;\n
  2129. + *          # Set the state as Statemachine is not ready
  2130. + * @param  N/A
  2131. + * @retval N/A
  2132. + * @note
  2133. + */
  2134. +void felica_statemachine_exit(void)
  2135. +{
  2136. +   pr_debug(PRT_NAME ": %s\n", __func__);
  2137. +
  2138. +   state = BEFORE_INIT;
  2139. +}
  2140. diff -ruN a/4.1.B.0.431//vendor/semc/hardware/felica/felica_statemachine.h b/4.1.B.0.479//vendor/semc/hardware/felica/felica_statemachine.h
  2141. --- a/4.1.B.0.431//vendor/semc/hardware/felica/felica_statemachine.h    1970-01-01 09:00:00.000000000 +0900
  2142. +++ b/4.1.B.0.479//vendor/semc/hardware/felica/felica_statemachine.h    2012-06-25 19:30:44.000000000 +0900
  2143. @@ -0,0 +1,40 @@
  2144. +/* vendor/semc/hardware/felica/felica_statemachine.h
  2145. + *
  2146. + * Copyright (C) 2010 Sony Ericsson Mobile Communications AB.
  2147. + *
  2148. + * Author: Hiroaki Kuriyama <[email protected]>
  2149. + *
  2150. + * This program is free software; you can redistribute it and/or modify
  2151. + * it under the terms of the GNU General Public License version 2, as
  2152. + * published by the Free Software Foundation; either version 2
  2153. + * of the License, or (at your option) any later version.
  2154. + */
  2155. +
  2156. +#ifndef _FELICA_STATEMACHINE_H
  2157. +#define _FELICA_STATEMACHINE_H
  2158. +
  2159. +#define STATEMACHINE_ERROR (-100)
  2160. +
  2161. +struct transition_struct {
  2162. +   int (*action)(void *data);
  2163. +   int nextstate;
  2164. +};
  2165. +
  2166. +struct event_struct {
  2167. +   int ev;
  2168. +   void *evdata;
  2169. +};
  2170. +
  2171. +struct result_struct {
  2172. +   int retval;
  2173. +   int ev;
  2174. +   int state;
  2175. +};
  2176. +
  2177. +struct result_struct felica_event_handle(struct event_struct);
  2178. +int felica_request_nextevent(struct event_struct);
  2179. +
  2180. +int felica_statemachine_init(void);
  2181. +void felica_statemachine_exit(void);
  2182. +
  2183. +#endif
  2184. diff -ruN a/4.1.B.0.431//vendor/semc/hardware/felica/felica_statemachine_userdata.h b/4.1.B.0.479//vendor/semc/hardware/felica/felica_statemachine_userdata.h
  2185. --- a/4.1.B.0.431//vendor/semc/hardware/felica/felica_statemachine_userdata.h   1970-01-01 09:00:00.000000000 +0900
  2186. +++ b/4.1.B.0.479//vendor/semc/hardware/felica/felica_statemachine_userdata.h   2012-06-25 19:30:44.000000000 +0900
  2187. @@ -0,0 +1,128 @@
  2188. +/* vendor/semc/hardware/felica/felica_statemachine_userdata.h
  2189. + *
  2190. + * Copyright (C) 2010 Sony Ericsson Mobile Communications AB.
  2191. + *
  2192. + * Author: Hiroaki Kuriyama <[email protected]>
  2193. + *
  2194. + * This program is free software; you can redistribute it and/or modify
  2195. + * it under the terms of the GNU General Public License version 2, as
  2196. + * published by the Free Software Foundation; either version 2
  2197. + * of the License, or (at your option) any later version.
  2198. + */
  2199. +
  2200. +#ifndef _FELICA_STATEMACHINE_USERDATA_H
  2201. +#define _FELICA_STATEMACHINE_USERDATA_H
  2202. +
  2203. +#include "felica_statemachine.h"
  2204. +
  2205. +/* Enumration of State */
  2206. +enum states {
  2207. +   uart_closed,
  2208. +   uart_open_idle,
  2209. +   uart_open_rx,
  2210. +   uart_open_tx,
  2211. +   __end_of_state
  2212. +};
  2213. +
  2214. +/* Enumration of Event */
  2215. +enum events {
  2216. +   open_syscall,
  2217. +   close_syscall,
  2218. +   read_syscall,
  2219. +   available_syscall,
  2220. +   write_syscall,
  2221. +   fsync_syscall,
  2222. +   exec_close_sig,
  2223. +   exec_fsync_sig,
  2224. +   receive_1byte_sig,
  2225. +   rx_complete_sig,
  2226. +   rx_to_idle_sig,
  2227. +   tx_complete_sig,
  2228. +   fsync_timeout_sig,
  2229. +   uartdm_error_sig,
  2230. +   __end_of_event
  2231. +};
  2232. +
  2233. +int felica_do_open_seq(void *);
  2234. +int felica_do_open_again(void *);
  2235. +int felica_do_close_check(void *);
  2236. +int felica_do_close_seq(void *);
  2237. +int felica_do_read_seq(void *);
  2238. +int felica_do_available_seq(void *);
  2239. +int felica_do_write_seq(void *);
  2240. +int felica_do_fsync_check(void *);
  2241. +int felica_do_fsync_reserve(void *);
  2242. +int felica_do_fsync_cancel(void *);
  2243. +int felica_do_rx_start(void *);
  2244. +int felica_do_rx_finish(void *);
  2245. +int felica_do_rx_reset(void *);
  2246. +int felica_do_tx_start(void *);
  2247. +int felica_do_tx_finish(void *);
  2248. +int felica_do_tx_reset(void *);
  2249. +int felica_do_rx_to_idle(void *);
  2250. +int felica_do_nothing(void *);
  2251. +
  2252. +static struct transition_struct tran[__end_of_state][__end_of_event] = {
  2253. +   /* Transitions @ UART CLOSED state*/
  2254. +   { {felica_do_open_seq,      uart_open_idle},
  2255. +     {felica_do_nothing,       uart_closed},
  2256. +     {felica_do_nothing,       uart_closed},
  2257. +     {felica_do_nothing,       uart_closed},
  2258. +     {felica_do_nothing,       uart_closed},
  2259. +     {felica_do_nothing,       uart_closed},
  2260. +     {felica_do_nothing,       uart_closed},
  2261. +     {felica_do_nothing,       uart_closed},
  2262. +     {felica_do_nothing,       uart_closed},
  2263. +     {felica_do_nothing,       uart_closed},
  2264. +     {felica_do_nothing,       uart_closed},
  2265. +     {felica_do_nothing,       uart_closed},
  2266. +     {felica_do_nothing,       uart_closed},
  2267. +     {felica_do_nothing,       uart_closed} },
  2268. +   /* Transitions @ UART OPEN IDLE state*/
  2269. +   { {felica_do_open_again,    uart_open_idle},
  2270. +     {felica_do_close_check,   uart_open_idle},
  2271. +     {felica_do_read_seq,      uart_open_idle},
  2272. +     {felica_do_available_seq, uart_open_idle},
  2273. +     {felica_do_write_seq,     uart_open_idle},
  2274. +     {felica_do_fsync_check,   uart_open_idle},
  2275. +     {felica_do_close_seq,     uart_closed},
  2276. +     {felica_do_tx_start,      uart_open_tx},
  2277. +     {felica_do_rx_start,      uart_open_rx},
  2278. +     {felica_do_nothing,       uart_open_idle},
  2279. +     {felica_do_nothing,       uart_open_idle},
  2280. +     {felica_do_nothing,       uart_open_idle},
  2281. +     {felica_do_nothing,       uart_open_idle},
  2282. +     {felica_do_nothing,       uart_open_idle} },
  2283. +   /* Transitions @ UART OPEN RX state*/
  2284. +   { {felica_do_open_again,    uart_open_rx},
  2285. +     {felica_do_close_check,   uart_open_rx},
  2286. +     {felica_do_read_seq,      uart_open_rx},
  2287. +     {felica_do_available_seq, uart_open_rx},
  2288. +     {felica_do_write_seq,     uart_open_rx},
  2289. +     {felica_do_fsync_reserve, uart_open_rx},
  2290. +     {felica_do_close_seq,     uart_closed},
  2291. +     {felica_do_tx_start,      uart_open_tx},
  2292. +     {felica_do_rx_start,      uart_open_rx},
  2293. +     {felica_do_rx_finish,     uart_open_rx},
  2294. +     {felica_do_rx_to_idle,    uart_open_idle},
  2295. +     {felica_do_nothing,       uart_open_rx},
  2296. +     {felica_do_fsync_cancel,  uart_open_rx},
  2297. +     {felica_do_rx_reset,      uart_open_rx} },
  2298. +   /* Transitions @ UART OPEN TX state*/
  2299. +   { {felica_do_open_again,    uart_open_tx},
  2300. +     {felica_do_close_check,   uart_open_tx},
  2301. +     {felica_do_read_seq,      uart_open_tx},
  2302. +     {felica_do_available_seq, uart_open_tx},
  2303. +     {felica_do_nothing,       uart_open_tx},
  2304. +     {felica_do_nothing,       uart_open_tx},
  2305. +     {felica_do_close_seq,     uart_closed},
  2306. +     {felica_do_nothing,       uart_open_tx},
  2307. +     {felica_do_nothing,       uart_open_tx},
  2308. +     {felica_do_nothing,       uart_open_tx},
  2309. +     {felica_do_nothing,       uart_open_tx},
  2310. +     {felica_do_tx_finish,     uart_open_idle},
  2311. +     {felica_do_tx_reset,      uart_open_idle},
  2312. +     {felica_do_tx_reset,      uart_open_idle} }
  2313. +};
  2314. +
  2315. +#endif
  2316. diff -ruN a/4.1.B.0.431//vendor/semc/hardware/felica/felica_txbuf.c b/4.1.B.0.479//vendor/semc/hardware/felica/felica_txbuf.c
  2317. --- a/4.1.B.0.431//vendor/semc/hardware/felica/felica_txbuf.c   1970-01-01 09:00:00.000000000 +0900
  2318. +++ b/4.1.B.0.479//vendor/semc/hardware/felica/felica_txbuf.c   2012-06-25 19:30:44.000000000 +0900
  2319. @@ -0,0 +1,218 @@
  2320. +/* vendor/semc/hardware/felica/felica_txbuf.c
  2321. + *
  2322. + * Copyright (C) 2010 Sony Ericsson Mobile Communications AB.
  2323. + *
  2324. + * Author: Hiroaki Kuriyama <[email protected]>
  2325. + *
  2326. + * This program is free software; you can redistribute it and/or modify
  2327. + * it under the terms of the GNU General Public License version 2, as
  2328. + * published by the Free Software Foundation; either version 2
  2329. + * of the License, or (at your option) any later version.
  2330. + */
  2331. +
  2332. +#include <linux/module.h>
  2333. +#include <linux/kernel.h>
  2334. +#include <linux/init.h>
  2335. +#include <linux/types.h>
  2336. +#include <linux/stddef.h>
  2337. +#include <linux/dma-mapping.h>
  2338. +#include <linux/uaccess.h>
  2339. +#include "felica_txbuf.h"
  2340. +
  2341. +#define PRT_NAME "txbuf"
  2342. +
  2343. +/* DEBUG_TXBUF_DUMP : 0 = without dump, 1 = with dump */
  2344. +#define DEBUG_TXBUF_DUMP 0
  2345. +
  2346. +struct txbuf_all {
  2347. +   int ptr;
  2348. +   int num;
  2349. +   char *buf;
  2350. +   dma_addr_t dmabase;
  2351. +};
  2352. +
  2353. +static struct txbuf_all txbuf;
  2354. +
  2355. +
  2356. +/**
  2357. + * @brief  Clear TX buffer
  2358. + * @param  N/A
  2359. + * @retval N/A
  2360. + * @note
  2361. + */
  2362. +void felica_txbuf_clear(void)
  2363. +{
  2364. +   pr_debug(PRT_NAME ": %s\n", __func__);
  2365. +
  2366. +   txbuf.num = 0;
  2367. +   txbuf.ptr = 0;
  2368. +}
  2369. +
  2370. +/**
  2371. + * @brief  Count the number of the stored data in TX buffer
  2372. + * @param  N/A
  2373. + * @retval 0/Positive : the number of the stored data
  2374. + * @retval Negative   : Failure\n
  2375. + *           -ENODEV = TX buf not initialized
  2376. + * @note
  2377. + */
  2378. +int felica_txbuf_count(void)
  2379. +{
  2380. +   pr_debug(PRT_NAME ": %s\n", __func__);
  2381. +
  2382. +   if (!txbuf.buf) {
  2383. +       pr_err(PRT_NAME ": Error. TX buf not initialized.\n");
  2384. +       return -ENODEV;
  2385. +   }
  2386. +
  2387. +   return txbuf.num - txbuf.ptr;
  2388. +}
  2389. +
  2390. +/**
  2391. + * @brief  Copy user space data to the TX buffer
  2392. + * @param  buf : Pointer to User space buffer
  2393. + * @param  len : Date length to copy
  2394. + * @retval Positive : Number of the data copied successfully.
  2395. + * @retval Negative : Failure\n
  2396. + *           -EINVAL = Invalid arguments\n
  2397. + *           -ENODEV = TX buf not initialized
  2398. + *           -EFBIG  = Data is too big\n
  2399. + *           -EFAULT = Data copy error
  2400. + * @note
  2401. + */
  2402. +int felica_txbuf_puts(const char __user *buf, int len)
  2403. +{
  2404. +   int ret;
  2405. +   int rest;
  2406. +
  2407. +#if DEBUG_TXBUF_DUMP
  2408. +   int i;
  2409. +#endif
  2410. +
  2411. +   pr_debug(PRT_NAME ": %s\n", __func__);
  2412. +
  2413. +   if (0 >= len || !buf) {
  2414. +       pr_err(PRT_NAME ": Error. Invalid argument.\n");
  2415. +       return -EINVAL;
  2416. +   }
  2417. +   if (!txbuf.buf) {
  2418. +       pr_err(PRT_NAME ": Error. TX buf not initialized.\n");
  2419. +       return -ENODEV;
  2420. +   }
  2421. +
  2422. +   rest = TXBUF_SIZE - txbuf.num;
  2423. +
  2424. +   if (len > rest) {
  2425. +       pr_err(PRT_NAME ": Error. Too many data to write.\n");
  2426. +       return -EFBIG;
  2427. +   }
  2428. +
  2429. +   ret = copy_from_user(txbuf.buf + txbuf.num, buf, len);
  2430. +   if (ret) {
  2431. +       pr_err(PRT_NAME ": Error. copy_from_user failure.\n");
  2432. +       return -EFAULT;
  2433. +   }
  2434. +
  2435. +#if DEBUG_TXBUF_DUMP
  2436. +   printk("TXputs dump: ");
  2437. +   for (i = 0; i < len; i++)
  2438. +       printk("%02x ", txbuf.buf[txbuf.num + i]);
  2439. +   printk("\n");
  2440. +#endif
  2441. +
  2442. +   txbuf.num += len;
  2443. +
  2444. +   return len;
  2445. +}
  2446. +
  2447. +/**
  2448. + * @brief  Return DMA address pointer to pull data
  2449. + * @param  N/A
  2450. + * @retval Valid-address : DMA address to pull
  2451. + * @retval 0 : No space to pull
  2452. + * @note
  2453. + */
  2454. +dma_addr_t felica_txbuf_pull_pointer(void)
  2455. +{
  2456. +   pr_debug(PRT_NAME ": %s\n", __func__);
  2457. +
  2458. +   if (txbuf.ptr == txbuf.num)
  2459. +       return 0;
  2460. +
  2461. +   return txbuf.dmabase + txbuf.ptr;
  2462. +}
  2463. +
  2464. +/**
  2465. + * @brief  Update TX buffer status according to the pushed data.
  2466. + * @param  len      : Data length already pushed
  2467. + * @retval 0        : Success
  2468. + * @retval Negative : Failure\n
  2469. + *           -EINVAL = Invalid argument\n
  2470. + *           -ENODEV = TX buf not initialized
  2471. + * @note
  2472. + */
  2473. +int felica_txbuf_pull_status_update(int len)
  2474. +{
  2475. +   pr_debug(PRT_NAME ": %s\n", __func__);
  2476. +
  2477. +   if (0 >= len || TXBUF_SIZE < len) {
  2478. +       pr_err(PRT_NAME ": Error. Invalid arg for pull status.\n");
  2479. +       return -EINVAL;
  2480. +   }
  2481. +   if (!txbuf.buf) {
  2482. +       pr_err(PRT_NAME ": Error. TX buf not initialized.\n");
  2483. +       return -ENODEV;
  2484. +   }
  2485. +
  2486. +   if (txbuf.ptr + len > txbuf.num) {
  2487. +       pr_err(PRT_NAME ": Error. Invalid arg, ptr overtakes num.\n");
  2488. +       return -EINVAL;
  2489. +   }
  2490. +   txbuf.ptr += len;
  2491. +
  2492. +   return 0;
  2493. +}
  2494. +
  2495. +/**
  2496. + * @brief  Initialize & alloc TX buffer
  2497. + * @details This function executes;\n
  2498. + *          # Alloc TX buffer\n
  2499. + *          # Call TX buffer clear
  2500. + * @param  N/A
  2501. + * @retval 0 : Success
  2502. + * @retval -ENOMEM : Error, no enough memory.
  2503. + * @note
  2504. + */
  2505. +int felica_txbuf_init(void)
  2506. +{
  2507. +   pr_debug(PRT_NAME ": %s\n", __func__);
  2508. +
  2509. +   txbuf.buf = dma_alloc_coherent(NULL, sizeof(char) * TXBUF_SIZE,
  2510. +                   &txbuf.dmabase, GFP_KERNEL);
  2511. +   if (!txbuf.buf) {
  2512. +       pr_err(PRT_NAME ": Error. No enough mem for TXbuf.\n");
  2513. +       return -ENOMEM;
  2514. +   }
  2515. +
  2516. +   felica_txbuf_clear();
  2517. +
  2518. +   return 0;
  2519. +}
  2520. +
  2521. +/**
  2522. + * @brief  Release TX buffer
  2523. + * @details This function executes;\n
  2524. + *          # Release TX buffer
  2525. + * @param  N/A
  2526. + * @retval N/A
  2527. + * @note
  2528. + */
  2529. +void felica_txbuf_exit(void)
  2530. +{
  2531. +   pr_debug(PRT_NAME ": %s\n", __func__);
  2532. +
  2533. +   dma_free_coherent(NULL, sizeof(char) * TXBUF_SIZE,
  2534. +                   txbuf.buf, txbuf.dmabase);
  2535. +   txbuf.buf = NULL;
  2536. +}
  2537. +
  2538. diff -ruN a/4.1.B.0.431//vendor/semc/hardware/felica/felica_txbuf.h b/4.1.B.0.479//vendor/semc/hardware/felica/felica_txbuf.h
  2539. --- a/4.1.B.0.431//vendor/semc/hardware/felica/felica_txbuf.h   1970-01-01 09:00:00.000000000 +0900
  2540. +++ b/4.1.B.0.479//vendor/semc/hardware/felica/felica_txbuf.h   2012-06-25 19:30:44.000000000 +0900
  2541. @@ -0,0 +1,26 @@
  2542. +/* vendor/semc/hardware/felica/felica_txbuf.h
  2543. + *
  2544. + * Copyright (C) 2010 Sony Ericsson Mobile Communications AB.
  2545. + *
  2546. + * Author: Hiroaki Kuriyama <[email protected]>
  2547. + *
  2548. + * This program is free software; you can redistribute it and/or modify
  2549. + * it under the terms of the GNU General Public License version 2, as
  2550. + * published by the Free Software Foundation; either version 2
  2551. + * of the License, or (at your option) any later version.
  2552. + */
  2553. +
  2554. +#ifndef _FELICA_TXBUF_H
  2555. +#define _FELICA_TXBUF_H
  2556. +
  2557. +#define TXBUF_SIZE 260
  2558. +
  2559. +int felica_txbuf_init(void);
  2560. +void felica_txbuf_exit(void);
  2561. +int felica_txbuf_count(void);
  2562. +void felica_txbuf_clear(void);
  2563. +int felica_txbuf_puts(const char __user *, int);
  2564. +dma_addr_t felica_txbuf_pull_pointer(void);
  2565. +int felica_txbuf_pull_status_update(int);
  2566. +
  2567. +#endif
  2568. diff -ruN a/4.1.B.0.431//vendor/semc/hardware/felica/felica_uart.c b/4.1.B.0.479//vendor/semc/hardware/felica/felica_uart.c
  2569. --- a/4.1.B.0.431//vendor/semc/hardware/felica/felica_uart.c    1970-01-01 09:00:00.000000000 +0900
  2570. +++ b/4.1.B.0.479//vendor/semc/hardware/felica/felica_uart.c    2012-06-25 19:30:44.000000000 +0900
  2571. @@ -0,0 +1,1118 @@
  2572. +/* vendor/semc/hardware/felica/felica_uart.c
  2573. + *
  2574. + * Copyright (C) 2010 Sony Ericsson Mobile Communications AB.
  2575. + *
  2576. + * Author: Hiroaki Kuriyama <[email protected]>
  2577. + *
  2578. + * This program is free software; you can redistribute it and/or modify
  2579. + * it under the terms of the GNU General Public License version 2, as
  2580. + * published by the Free Software Foundation; either version 2
  2581. + * of the License, or (at your option) any later version.
  2582. + */
  2583. +
  2584. +#include <linux/module.h>
  2585. +#include <linux/kernel.h>
  2586. +#include <linux/init.h>
  2587. +#include <linux/types.h>
  2588. +#include <linux/stddef.h>
  2589. +#include <linux/fs.h>
  2590. +#include <linux/miscdevice.h>
  2591. +#include <linux/mfd/pmic8058.h>
  2592. +#include <linux/uaccess.h>
  2593. +#include <linux/gpio.h>
  2594. +#include <linux/delay.h>
  2595. +#include "semc_felica_ext.h"
  2596. +#include "felica_uart.h"
  2597. +#include "msm_uartdm.h"
  2598. +#include "msm_uartmux.h"
  2599. +#include "felica_rxbuf.h"
  2600. +#include "felica_txbuf.h"
  2601. +#include "felica_statemachine.h"
  2602. +#include "felica_statemachine_userdata.h"
  2603. +
  2604. +#define PRT_NAME "felica uart"
  2605. +
  2606. +struct felica_uart_data {
  2607. +   struct felica_uart_pfdata   *pfdata;
  2608. +   /* Reference count of FeliCa UART */
  2609. +   int         refcnt;
  2610. +   /* TX reservation during RX */
  2611. +   enum {no, yes}      tx_reserved;
  2612. +   /* Waitquese variables for fsync */
  2613. +   wait_queue_head_t   wait_fsync;
  2614. +   int         condition_fsync;
  2615. +   /* Result of fsync */
  2616. +   enum {success, error}   result_fsync;
  2617. +   /* Previous available result */
  2618. +   int         prev_avail;
  2619. +};
  2620. +
  2621. +static struct felica_uart_data *fluart;
  2622. +
  2623. +
  2624. +/**
  2625. + * @brief  Action to do nothing
  2626. + * @param  nodata : (unused)
  2627. + * @retval 0
  2628. + * @note
  2629. + */
  2630. +int felica_do_nothing(void *nodata)
  2631. +{
  2632. +   pr_debug(PRT_NAME ": %s\n", __func__);
  2633. +
  2634. +   return 0;
  2635. +}
  2636. +
  2637. +/**
  2638. + * @brief   Execute OPEN sequence of FeliCa UART, after checking UART MUX state
  2639. + * @details This function executes;\n
  2640. + *            # Check UART MUX\n
  2641. + *            # Set UART MUX for FeliCa\n
  2642. + *            # Call UARTDM open function\n
  2643. + *            # Clear tx_reserved variable\n
  2644. + *            # Call UART 1byte-reception enable function\n
  2645. + *            # Increment the reference count to 1
  2646. + * @param   nodata   : (unused)
  2647. + * @retval  0        : Success
  2648. + * @retval  Negative : Failure\n
  2649. + *            -EBUSY = The UART is occupied by another\n
  2650. + *            -EIO   = UART MUX access error / UARTDM open error /
  2651. + *                     Cannot enable 1byte-reception
  2652. + * @note
  2653. + */
  2654. +int felica_do_open_seq(void *nodata)
  2655. +{
  2656. +   int ret;
  2657. +
  2658. +   pr_debug(PRT_NAME ": %s\n", __func__);
  2659. +
  2660. +   /* Check UART MUX state*/
  2661. +   ret = msm_uartmux_get();
  2662. +   if (0 > ret) {
  2663. +       pr_err(PRT_NAME ": Error. Cannot get UART MUX.\n");
  2664. +       ret = -EIO;
  2665. +       goto err_uartmux_get;
  2666. +   } else if (ret != fluart->pfdata->uartmux_neutral) {
  2667. +       pr_err(PRT_NAME ": Error. UART MUX not available.\n");
  2668. +       ret = -EBUSY;
  2669. +       goto err_uartmux_get;
  2670. +   }
  2671. +
  2672. +   /* Set UART MUX for FeliCa */
  2673. +   ret = msm_uartmux_set(fluart->pfdata->uartmux_felica);
  2674. +   if (ret) {
  2675. +       pr_err(PRT_NAME ": Error. Cannot set UART MUX.\n");
  2676. +       ret = -EIO;
  2677. +       goto err_uartmux_set;
  2678. +   }
  2679. +
  2680. +   /* Call UARTDM open function */
  2681. +   ret = msm_uartdm_open();
  2682. +   if (ret) {
  2683. +       pr_err(PRT_NAME ": Error. UART Open failed.\n");
  2684. +       ret = -EIO;
  2685. +       goto err_uartdm_open;
  2686. +   }
  2687. +
  2688. +   /* Clear tx_reserved variable */
  2689. +   fluart->tx_reserved = no;
  2690. +
  2691. +   /* Call UART 1byte-reception enable function */
  2692. +   ret = msm_uartdm_rcv_1byte_enable();
  2693. +   if (ret) {
  2694. +       pr_err(PRT_NAME ": Error. Cannot enable RCV.\n");
  2695. +       ret = -EIO;
  2696. +       goto err_uartdm_rcv_1byte_enable;
  2697. +   }
  2698. +
  2699. +   /* Increment the reference count to 1 */
  2700. +   fluart->refcnt = 1;
  2701. +
  2702. +   return 0;
  2703. +
  2704. +err_uartdm_rcv_1byte_enable:
  2705. +   msm_uartdm_close();
  2706. +err_uartdm_open:
  2707. +   msm_uartmux_set(fluart->pfdata->uartmux_neutral);
  2708. +err_uartmux_set:
  2709. +err_uartmux_get:
  2710. +   return ret;
  2711. +}
  2712. +
  2713. +/**
  2714. + * @brief   Execute Open again
  2715. + * @details This function executes;\n
  2716. + *            # Increment the reference count to 2
  2717. + * @param   nodata : (unused)
  2718. + * @retval  0      : Success
  2719. + * @note
  2720. + */
  2721. +int felica_do_open_again(void *nodata)
  2722. +{
  2723. +   pr_debug(PRT_NAME ": %s\n", __func__);
  2724. +
  2725. +   fluart->refcnt = 2;
  2726. +
  2727. +   return 0;
  2728. +}
  2729. +
  2730. +/**
  2731. + * @brief   Check if UART can be closed. Issue EXEC_CLOSE_SIG if possible.
  2732. + * @details This function executes;\n
  2733. + *            # Decrement the reference count\n
  2734. + *            # If it becomes 0 or less, request EXEC_CLOSE_SIG event.
  2735. + * @param   nodata : (unused)
  2736. + * @retval  0      : Success
  2737. + * @note
  2738. + */
  2739. +int felica_do_close_check(void *nodata)
  2740. +{
  2741. +   struct event_struct evset = {exec_close_sig, NULL};
  2742. +
  2743. +   pr_debug(PRT_NAME ": %s\n", __func__);
  2744. +
  2745. +   fluart->refcnt--;
  2746. +   if (0 >= fluart->refcnt)
  2747. +       felica_request_nextevent(evset);
  2748. +
  2749. +   return 0;
  2750. +}
  2751. +
  2752. +/**
  2753. + * @brief   Execute Close sequence of FeliCa UART port.
  2754. + * @details This function executes;\n
  2755. + *            # Call UART 1byte-reception disable function\n
  2756. + *            # Call UARTDM close function\n
  2757. + *            # Set UART MUX to Neutral
  2758. + * @param   nodata   : (unused)
  2759. + * @retval  0        : Success
  2760. + * @retval  Negative : Failure\n
  2761. + *            -EIO = Cannot disable 1byte-reception / UARTDM close error /
  2762. + *                   UART MUX write error
  2763. + * @note
  2764. + */
  2765. +int felica_do_close_seq(void *nodata)
  2766. +{
  2767. +   int ret;
  2768. +
  2769. +   pr_debug(PRT_NAME ": %s\n", __func__);
  2770. +
  2771. +   ret = msm_uartdm_rcv_1byte_disable();
  2772. +   if (ret) {
  2773. +       pr_err(PRT_NAME ": Error. Cannot disable RCV.\n");
  2774. +       ret = -EIO;
  2775. +       goto err_uartdm_rcv_disable;
  2776. +   }
  2777. +
  2778. +   ret = msm_uartdm_close();
  2779. +   if (ret) {
  2780. +       pr_err(PRT_NAME ": Error. UARTDM close failed.\n");
  2781. +       ret = -EIO;
  2782. +       goto err_uartdm_close;
  2783. +   }
  2784. +
  2785. +   ret = msm_uartmux_set(fluart->pfdata->uartmux_neutral);
  2786. +   if (ret) {
  2787. +       pr_err(PRT_NAME ": Error. Cannot set UART MUX.\n");
  2788. +       ret = -EIO;
  2789. +       goto err_uartmux_set;
  2790. +   }
  2791. +
  2792. +   return 0;
  2793. +
  2794. +err_uartdm_rcv_disable:
  2795. +   msm_uartdm_close();
  2796. +err_uartdm_close:
  2797. +   msm_uartmux_set(fluart->pfdata->uartmux_neutral);
  2798. +err_uartmux_set:
  2799. +   return ret;
  2800. +}
  2801. +
  2802. +/**
  2803. + * @brief   Execute Read sequence of FeliCa UART port.
  2804. + * @details This function executes;\n
  2805. + *            # Check data length in RX buffer\n
  2806. + *            # If data exists, get char data from RX buffer
  2807. + * @param   data     : Data structure for Read\n
  2808. + *           .buf    : Pointer to User space\n
  2809. + *           .count  : Length to read
  2810. + * @retval  Positive : Success. Length of the data read successfully
  2811. + * @retval  0        : Success. No data to read
  2812. + * @retval  Negative : Failure\n
  2813. + * @retval    -EINVAL = The arguments are invalid.\n
  2814. + * @retval    -EFAULT = Data cannot be copied from RX buffer.
  2815. + * @note
  2816. + */
  2817. +int felica_do_read_seq(void *data)
  2818. +{
  2819. +   int ret;
  2820. +   struct read_data_struct *dataset = data;
  2821. +
  2822. +   pr_debug(PRT_NAME ": %s\n", __func__);
  2823. +
  2824. +   if (!dataset->buf || !dataset->count) {
  2825. +       pr_err(PRT_NAME ": Error. Invalid arg @read.");
  2826. +       return -EINVAL;
  2827. +   }
  2828. +
  2829. +   ret = felica_rxbuf_count();
  2830. +   if (0 > ret) {
  2831. +       pr_err(PRT_NAME ": Error. RXbuf check failed.");
  2832. +       return -EFAULT;
  2833. +   }
  2834. +
  2835. +   if (0 < ret) {
  2836. +       ret = felica_rxbuf_gets(dataset->buf, dataset->count);
  2837. +       if (0 > ret) {
  2838. +           pr_err(PRT_NAME ": Error. RXbuf access failed.");
  2839. +           ret = -EFAULT;
  2840. +       }
  2841. +   }
  2842. +
  2843. +   return ret;
  2844. +}
  2845. +
  2846. +/**
  2847. + * @brief   Execute Available sequence of FeliCa UART port.
  2848. + * @details This function executes;\n
  2849. + *            # Check data length in RX buffer
  2850. + * @param   nodata     : (unused)
  2851. + * @retval  0/Positive : Success. Length of data stored in RX buffer
  2852. + * @retval  Negative   : Failure\n
  2853. + *            -EFAULT = RX buffer access failed.
  2854. + * @note
  2855. + */
  2856. +int felica_do_available_seq(void *nodata)
  2857. +{
  2858. +   int ret;
  2859. +
  2860. +   pr_debug(PRT_NAME ": %s\n", __func__);
  2861. +
  2862. +   ret = felica_rxbuf_count();
  2863. +   if (0 > ret) {
  2864. +       pr_err(PRT_NAME ": Error. RXbuf check failed.");
  2865. +       return -EFAULT;
  2866. +   }
  2867. +
  2868. +   return ret;
  2869. +}
  2870. +
  2871. +/**
  2872. + * @brief   Execute Write sequence of FeliCa UART port.
  2873. + * @details This function executes;\n
  2874. + *            # Put char data to TX buffer
  2875. + * @param   data     : Data structure for Write\n
  2876. + *           .buf    : Pointer to User space\n
  2877. + *           .count  : Length to write
  2878. + * @retval  Positive : Success. Length of the data written successfully
  2879. + * @retval  Negative : Failure\n
  2880. + *            -EINVAL = The arguments are invalid.\n
  2881. + *            -EFAULT = Data cannot be copied to TX buffer.
  2882. + * @note
  2883. + */
  2884. +int felica_do_write_seq(void *data)
  2885. +{
  2886. +   int ret;
  2887. +   struct write_data_struct *dataset = data;
  2888. +
  2889. +   pr_debug(PRT_NAME ": %s\n", __func__);
  2890. +
  2891. +   if (!dataset->buf || !dataset->count) {
  2892. +       pr_err(PRT_NAME ": Error. Invalid arg @write.");
  2893. +       return -EINVAL;
  2894. +   }
  2895. +
  2896. +   ret = felica_txbuf_puts(dataset->buf, dataset->count);
  2897. +   if (0 > ret) {
  2898. +       pr_err(PRT_NAME ": Error. TXbuf access failed.");
  2899. +       return -EFAULT;
  2900. +   }
  2901. +
  2902. +   return ret;
  2903. +}
  2904. +
  2905. +/**
  2906. + * @brief   Check if fsync should be executed. Issue EXE_FSYNC_SIG if necessary.
  2907. + * @details This function executes;\n
  2908. + *            # Count TX buffer\n
  2909. + *            # [If TX data exists,] request EXEC_FSYNC_SIG.
  2910. + * @param   nodata   : (unused)
  2911. + * @retval  0        : Success
  2912. + * @retval  Negative : Failure\n
  2913. + *            -ENODATA = No data for fsync.\n
  2914. + *            -EFAULT  = TX buffer check failed.
  2915. + * @note
  2916. + */
  2917. +int felica_do_fsync_check(void *nodata)
  2918. +{
  2919. +   int ret;
  2920. +   struct event_struct evset = {exec_fsync_sig, NULL};
  2921. +
  2922. +   pr_debug(PRT_NAME ": %s\n", __func__);
  2923. +
  2924. +   ret = felica_txbuf_count();
  2925. +   if (0 > ret) {
  2926. +       pr_err(PRT_NAME ": Error. TXbuf check failed.");
  2927. +       return -EFAULT;
  2928. +   } else if (0 == ret) {
  2929. +       pr_debug(PRT_NAME ": No data to do fsync.");
  2930. +       return -ENODATA;
  2931. +   }
  2932. +   felica_request_nextevent(evset);
  2933. +
  2934. +   return 0;
  2935. +}
  2936. +
  2937. +/**
  2938. + * @brief   Check if fsync should be executed, and reserve fsync if necessary.
  2939. + * @details This function executes;\n
  2940. + *            # Count TX buffer\n
  2941. + *            # [If TX data exists,] set tx_reserved variable as reserved.
  2942. + * @param   nodata   : (unused)
  2943. + * @retval  0        : Success
  2944. + * @retval  Negative : Failure\n
  2945. + *            -EFAULT  = TX buffer access failed.\n
  2946. + *            -ENODATA = No data for fsync.
  2947. + * @note
  2948. + */
  2949. +int felica_do_fsync_reserve(void *nodata)
  2950. +{
  2951. +   int ret;
  2952. +
  2953. +   pr_debug(PRT_NAME ": %s\n", __func__);
  2954. +
  2955. +   ret = felica_txbuf_count();
  2956. +   if (0 > ret) {
  2957. +       pr_err(PRT_NAME ": Error. TXbuf check failed.");
  2958. +       return -EFAULT;
  2959. +   } else if (0 == ret) {
  2960. +       pr_debug(PRT_NAME ": No data to do fsync.");
  2961. +       return -ENODATA;
  2962. +   }
  2963. +
  2964. +   fluart->tx_reserved = yes;
  2965. +
  2966. +   return 0;
  2967. +}
  2968. +
  2969. +/**
  2970. + * @brief   Cancel reserved fsync.
  2971. + * @details This function executes;\n
  2972. + *            # Set tx_reserved variable as not-reserved.
  2973. + * @param   nodata : (unused)
  2974. + * @retval  0      : Success
  2975. + * @note
  2976. + */
  2977. +int felica_do_fsync_cancel(void *nodata)
  2978. +{
  2979. +   pr_debug(PRT_NAME ": %s\n", __func__);
  2980. +
  2981. +   fluart->tx_reserved = no;
  2982. +
  2983. +   return 0;
  2984. +}
  2985. +
  2986. +/**
  2987. + * @brief   Start UARTDM RX transfer
  2988. + * @details This function executes;\n
  2989. + *            # Call UARTDM RX start function\n
  2990. + *            # If RX start failed, call UARTDM RX reset function.\n
  2991. + *            # If RX start failed, enable RX 1byte reception interrupt.
  2992. + * @param   nodata   : (unused)
  2993. + * @retval  0        : Success
  2994. + * @retval  Negative : Failure\n
  2995. + *            -EIO = UART RX start failed
  2996. + * @note
  2997. + */
  2998. +int felica_do_rx_start(void *nodata)
  2999. +{
  3000. +   int ret;
  3001. +
  3002. +   pr_debug(PRT_NAME ": %s\n", __func__);
  3003. +
  3004. +   ret = msm_uartdm_rx_start();
  3005. +   if (ret) {
  3006. +       pr_err(PRT_NAME ": Error. UART RX start failed.");
  3007. +       msm_uartdm_rx_reset();
  3008. +       msm_uartdm_rcv_1byte_enable();
  3009. +       return -EIO;
  3010. +   }
  3011. +
  3012. +   return 0;
  3013. +}
  3014. +
  3015. +/**
  3016. + * @brief   Execute finish sequence of UARTDM RX
  3017. + * @details This function executes;\n
  3018. + *            # Check UARTDM received byte\n
  3019. + *            # [If additional data exists,] request RECEIVE_1BYTE_SIG event.\n
  3020. + *            # [If no data but TX reserved,] request EXEC_FSYNC_SIG event.\n
  3021. + *            # [If else,] request RX_TO_IDLE_SIG event.
  3022. + * @param   nodata   : (unused)
  3023. + * @retval  0        : Success
  3024. + * @note
  3025. + */
  3026. +int felica_do_rx_finish(void *nodata)
  3027. +{
  3028. +   int ret;
  3029. +   struct event_struct evset = {receive_1byte_sig, NULL};
  3030. +
  3031. +   pr_debug(PRT_NAME ": %s\n", __func__);
  3032. +
  3033. +   ret = msm_uartdm_rcv_byte_check();
  3034. +   if (0 == ret) {
  3035. +       if (yes == fluart->tx_reserved)
  3036. +           evset.ev = exec_fsync_sig;
  3037. +       else
  3038. +           evset.ev = rx_to_idle_sig;
  3039. +   }
  3040. +   felica_request_nextevent(evset);
  3041. +
  3042. +   return 0;
  3043. +}
  3044. +
  3045. +/**
  3046. + * @brief   Reset UARTDM RX port
  3047. + * @details This function executes;\n
  3048. + *            # Call UARTDM RX reset function\n
  3049. + *            # Request RX_COMPLETE_SIG event.
  3050. + * @param   nodata   : (unused)
  3051. + * @retval  0        : Success.
  3052. + * @retval  Negative : Failure\n
  3053. + *            -EIO = UARTDM RX reset failed
  3054. + * @note
  3055. + */
  3056. +int felica_do_rx_reset(void *nodata)
  3057. +{
  3058. +   int ret;
  3059. +   struct event_struct evset = {rx_complete_sig, NULL};
  3060. +
  3061. +   pr_debug(PRT_NAME ": %s\n", __func__);
  3062. +
  3063. +   ret = msm_uartdm_rx_reset();
  3064. +   if (ret) {
  3065. +       pr_err(PRT_NAME ": Error. UARTDM RX reset failed.");
  3066. +       return -EIO;
  3067. +   }
  3068. +
  3069. +   felica_request_nextevent(evset);
  3070. +
  3071. +   return 0;
  3072. +}
  3073. +
  3074. +/**
  3075. + * @brief   Start UARTDM TX transfer
  3076. + * @details This function executes;\n
  3077. + *            # Set tx_reserved variable as not reserved.\n
  3078. + *            # Disable RX 1byte reception interrupt\n
  3079. + *            # Call UARTDM TX start function.
  3080. + * @param   nodata   : (unused)
  3081. + * @retval  0        : Success
  3082. + * @retval  Negative : Failure\n
  3083. + *            -EIO = Cannot disable 1byte-reception / UARTDM TX start failed
  3084. + * @note
  3085. + */
  3086. +int felica_do_tx_start(void *nodata)
  3087. +{
  3088. +   int ret;
  3089. +
  3090. +   pr_debug(PRT_NAME ": %s\n", __func__);
  3091. +
  3092. +   fluart->tx_reserved = no;
  3093. +
  3094. +   ret = msm_uartdm_rcv_1byte_disable();
  3095. +   if (ret) {
  3096. +       pr_err(PRT_NAME ": Error. Cannot disable RCV.\n");
  3097. +       return -EIO;
  3098. +   }
  3099. +
  3100. +   ret = msm_uartdm_tx_start();
  3101. +   if (ret) {
  3102. +       pr_err(PRT_NAME ": Error. UARTDM TX start failed.");
  3103. +       return -EIO;
  3104. +   }
  3105. +
  3106. +   return 0;
  3107. +}
  3108. +
  3109. +/**
  3110. + * @brief   Execute finish sequence of UARTDM TX
  3111. + * @details This function executes;\n
  3112. + *            # Clear TX buffer\n
  3113. + *            # Enable RX 1byte reception interrupt
  3114. + * @param   nodata   : (unused)
  3115. + * @retval  0        : Success.
  3116. + * @retval  Negative : Failure\n
  3117. + *            -EIO   = Cannot enable 1byte-reception
  3118. + * @note
  3119. + */
  3120. +int felica_do_tx_finish(void *nodata)
  3121. +{
  3122. +   int ret;
  3123. +
  3124. +   pr_debug(PRT_NAME ": %s\n", __func__);
  3125. +
  3126. +   felica_txbuf_clear();
  3127. +
  3128. +   ret = msm_uartdm_rcv_1byte_enable();
  3129. +   if (ret) {
  3130. +       pr_err(PRT_NAME ": Error. Cannot enable RCV.\n");
  3131. +       return -EIO;
  3132. +   }
  3133. +
  3134. +   return 0;
  3135. +}
  3136. +
  3137. +/**
  3138. + * @brief   Reset UARTDM TX port
  3139. + * @details This function executes;\n
  3140. + *            # Call UARTDM TX reset\n
  3141. + *            # Enable RX 1byte reception interrupt
  3142. + * @param   nodata   : (unused)
  3143. + * @retval  0        : Success.
  3144. + * @retval  Negative : Failure\n
  3145. + *            -EIO = UARTDM TX reset failed / Cannot enable 1byte-reception
  3146. + * @note
  3147. + */
  3148. +int felica_do_tx_reset(void *nodata)
  3149. +{
  3150. +   int ret;
  3151. +
  3152. +   pr_debug(PRT_NAME ": %s\n", __func__);
  3153. +
  3154. +   ret = msm_uartdm_tx_reset();
  3155. +   if (ret) {
  3156. +       pr_err(PRT_NAME ": Error. UARTDM TX reset failed.");
  3157. +       return -EIO;
  3158. +   }
  3159. +
  3160. +   ret = msm_uartdm_rcv_1byte_enable();
  3161. +   if (ret) {
  3162. +       pr_err(PRT_NAME ": Error. Cannot enable RCV.\n");
  3163. +       return -EIO;
  3164. +   }
  3165. +
  3166. +   return 0;
  3167. +}
  3168. +
  3169. +/**
  3170. + * @brief   Return from RX state to IDLE state
  3171. + * @details This function executes;\n
  3172. + *            # Enable RX 1byte reception interrupt
  3173. + * @param   nodata : (unused)
  3174. + * @retval  0      : Success.
  3175. + * @retval  Negative : Failure\n
  3176. + *            -EIO   = Cannot enable 1byte-reception
  3177. + * @note
  3178. + * @note
  3179. + */
  3180. +int felica_do_rx_to_idle(void *nodata)
  3181. +{
  3182. +   int ret;
  3183. +   pr_debug(PRT_NAME ": %s\n", __func__);
  3184. +
  3185. +   ret = msm_uartdm_rcv_1byte_enable();
  3186. +   if (ret) {
  3187. +       pr_err(PRT_NAME ": Error. Cannot enable RCV.\n");
  3188. +       return -EIO;
  3189. +   }
  3190. +
  3191. +   return 0;
  3192. +}
  3193. +
  3194. +/**
  3195. + * @brief   Handling RX 1byte reception callback
  3196. + * @details This function executes;\n
  3197. + *            # Issue RECEIVE_1BYTE_SIG event
  3198. + * @param   N/A
  3199. + * @retval  N/A
  3200. + * @note
  3201. + */
  3202. +void felica_cb_rcv_1byte(void)
  3203. +{
  3204. +   struct event_struct evset = {receive_1byte_sig, NULL};
  3205. +
  3206. +   pr_debug(PRT_NAME ": %s\n", __func__);
  3207. +
  3208. +   felica_event_handle(evset);
  3209. +}
  3210. +
  3211. +/**
  3212. + * @brief   Handling RX complete callback
  3213. + * @details This function executes;\n
  3214. + *            # Issue RX_COMPLETE_SIG event
  3215. + * @param   N/A
  3216. + * @retval  N/A
  3217. + * @note
  3218. + */
  3219. +void felica_cb_rx_complete(void)
  3220. +{
  3221. +   struct event_struct evset = {rx_complete_sig, NULL};
  3222. +
  3223. +   pr_debug(PRT_NAME ": %s\n", __func__);
  3224. +
  3225. +   felica_event_handle(evset);
  3226. +}
  3227. +
  3228. +/**
  3229. + * @brief   Handling RX error callback
  3230. + * @details This function executes;\n
  3231. + *            # Issue UARTDM_ERROR_SIG event
  3232. + * @param   N/A
  3233. + * @retval  N/A
  3234. + * @note
  3235. + */
  3236. +void felica_cb_rx_error(void)
  3237. +{
  3238. +   struct event_struct evset = {uartdm_error_sig, NULL};
  3239. +
  3240. +   pr_debug(PRT_NAME ": %s\n", __func__);
  3241. +
  3242. +   felica_event_handle(evset);
  3243. +}
  3244. +
  3245. +/**
  3246. + * @brief   Handling TX complete callback
  3247. + * @details This function executes;\n
  3248. + *            # Issue TX_COMPLETE_SIG event\n
  3249. + *            # Set result_fsync variable as success\n
  3250. + *            # Wakeup FSYNC wait
  3251. + * @param   N/A
  3252. + * @retval  N/A
  3253. + * @note
  3254. + */
  3255. +void felica_cb_tx_complete(void)
  3256. +{
  3257. +   struct event_struct evset = {tx_complete_sig, NULL};
  3258. +   struct result_struct result;
  3259. +
  3260. +   pr_debug(PRT_NAME ": %s\n", __func__);
  3261. +
  3262. +   result = felica_event_handle(evset);
  3263. +
  3264. +   fluart->result_fsync = success;
  3265. +
  3266. +   fluart->condition_fsync = 1;
  3267. +   wake_up(&fluart->wait_fsync);
  3268. +}
  3269. +
  3270. +/**
  3271. + * @brief   Handling TX error callback
  3272. + * @details This function executes;\n
  3273. + *            # Issue UARTDM_ERROR_SIG event\n
  3274. + *            # Set result_fsync variable as error\n
  3275. + *            # Wakeup FSYNC wait
  3276. + * @param   N/A
  3277. + * @retval  N/A
  3278. + */
  3279. +void felica_cb_tx_error(void)
  3280. +{
  3281. +   struct event_struct evset = {uartdm_error_sig, NULL};
  3282. +   struct result_struct result;
  3283. +
  3284. +   pr_debug(PRT_NAME ": %s\n", __func__);
  3285. +
  3286. +   result = felica_event_handle(evset);
  3287. +
  3288. +   fluart->result_fsync = error;
  3289. +
  3290. +   fluart->condition_fsync = 1;
  3291. +   wake_up(&fluart->wait_fsync);
  3292. +}
  3293. +
  3294. +/**
  3295. + * @brief   Handle OPEN system call of FeliCa UART
  3296. + * @details This function executes;\n
  3297. + *            # Issue OPEN_SYSCALL event
  3298. + * @param   inode    : (unused)
  3299. + * @param   file     : (unused)
  3300. + * @retval  0        : Success
  3301. + * @retval  Negative : Failure\n
  3302. + *            -EIO = Action failed.
  3303. + */
  3304. +static int felica_uart_open(struct inode *inode, struct file *file)
  3305. +{
  3306. +   struct event_struct evset = {open_syscall, NULL};
  3307. +   struct result_struct result;
  3308. +
  3309. +   pr_debug(PRT_NAME ": %s\n", __func__);
  3310. +
  3311. +   result = felica_event_handle(evset);
  3312. +
  3313. +   fluart->prev_avail = 0;
  3314. +
  3315. +   if (0 > result.retval)
  3316. +       return -EIO;
  3317. +
  3318. +   return 0;
  3319. +}
  3320. +
  3321. +/**
  3322. + * @brief   Handle CLOSE system call of FeliCa UART
  3323. + * @details This function executes;\n
  3324. + *            # Issue CLOSE_SYSCALL event
  3325. + * @param   inode    : (unused)
  3326. + * @param   file     : (unused)
  3327. + * @retval  Negative : Failure\n
  3328. + *            -EIO = Action failed.
  3329. + */
  3330. +static int felica_uart_release(struct inode *inode, struct file *file)
  3331. +{
  3332. +   struct event_struct evset = {close_syscall, NULL};
  3333. +   struct result_struct result;
  3334. +
  3335. +   pr_debug(PRT_NAME ": %s\n", __func__);
  3336. +
  3337. +   result = felica_event_handle(evset);
  3338. +
  3339. +   if (0 > result.retval)
  3340. +       return -EIO;
  3341. +
  3342. +   return 0;
  3343. +}
  3344. +
  3345. +/**
  3346. + * @brief   Handle READ system call of FeliCa UART
  3347. + * @details This function executes;\n
  3348. + *            # Issue READ_SYSCALL event\n
  3349. + *            # [Optional][If no data,] sleep
  3350. + * @param   file     : (unused)
  3351. + * @param   buf      : Destination of the read data
  3352. + * @param   count    : Data length to read
  3353. + * @param   offset   : (unused)
  3354. + * @retval  Positive : Success. Length of possibly read data
  3355. + * @retval  0        : Success. No data to read
  3356. + * @retval  Negative : Failure\n
  3357. + *            -EINVAL = The arguments are invalid.\n
  3358. + *            -EIO    = Action to read data failed.
  3359. + */
  3360. +static ssize_t felica_uart_read(struct file *file, char __user *buf,
  3361. +                   size_t count, loff_t *offset)
  3362. +{
  3363. +   struct read_data_struct dataset = {buf, count};
  3364. +   struct event_struct evset = {read_syscall, (void *) &dataset};
  3365. +   struct result_struct result;
  3366. +
  3367. +   pr_debug(PRT_NAME ": %s (%d)\n", __func__, count);
  3368. +
  3369. +   if (!buf || !count) {
  3370. +       pr_err(PRT_NAME ": Error. Invalid arg @read.\n");
  3371. +       return -EINVAL;
  3372. +   }
  3373. +
  3374. +   result = felica_event_handle(evset);
  3375. +   pr_debug(PRT_NAME ": Read result = %d.\n", result.retval);
  3376. +
  3377. +   /* [Optional][If no data,] sleep */
  3378. +   if ((0 == result.retval) && (0 < FELICA_UART_READ_MSLEEP)) {
  3379. +       pr_debug(PRT_NAME ": Read sleep(%dms).\n",
  3380. +                   FELICA_UART_READ_MSLEEP);
  3381. +       msleep(FELICA_UART_READ_MSLEEP);
  3382. +   }
  3383. +
  3384. +   if (0 > result.retval)
  3385. +       return -EIO;
  3386. +
  3387. +   return result.retval;
  3388. +}
  3389. +
  3390. +/**
  3391. + * @brief   Handle WRITE system call of FeliCa UART
  3392. + * @details This function executes;\n
  3393. + *            # Issue WRITE_SYSCALL event.
  3394. + * @param   file     : (unused)
  3395. + * @param   buf      : Source of the written data
  3396. + * @param   count    : Data length to write
  3397. + * @param   offset   : (unused)
  3398. + * @retval  Positive : Success. Length of the data written successfully.
  3399. + * @retval  Negative : Failure\n
  3400. + *            -EINVAL = The arguments are invalid.\n
  3401. + *            -EIO    = Action to write data failed.
  3402. + */
  3403. +static ssize_t felica_uart_write(struct file *file, const char __user *buf,
  3404. +                   size_t count, loff_t *offset)
  3405. +{
  3406. +   struct write_data_struct dataset =  {buf, count};
  3407. +   struct event_struct evset = {write_syscall, (void *) &dataset};
  3408. +   struct result_struct result;
  3409. +
  3410. +   pr_debug(PRT_NAME ": %s (%d)\n", __func__, count);
  3411. +
  3412. +   if (!buf || !count) {
  3413. +       pr_err(PRT_NAME ": Error. Invalid arg @available.\n");
  3414. +       return -EINVAL;
  3415. +   }
  3416. +
  3417. +   result = felica_event_handle(evset);
  3418. +
  3419. +   if (0 > result.retval)
  3420. +       return -EIO;
  3421. +
  3422. +   return result.retval;
  3423. +}
  3424. +
  3425. +/**
  3426. + * @brief   Handle FSYNC system call of FeliCa UART
  3427. + * @details This function executes;\n
  3428. + *            # Issue FSYNC_SYSCALL event\n
  3429. + *            # [If no TX data exists,] finish successfully.\n
  3430. + *            # Wait until TX completes.\n
  3431. + *            # [If wait timeout,] issue FSYNC_TIMOUT_SIG.\n
  3432. + *            # Check TX result.
  3433. + * @param   file     : (unused)
  3434. + * @param   dentry   : (unused)
  3435. + * @param   datasync : (unused)
  3436. + * @retval  0        : Success.
  3437. + * @retval  Negative : Failure\n
  3438. + *            -EFAULT = DMA transfer error occurred.
  3439. + *            -EAGAIN = Time out occurs.
  3440. + */
  3441. +static int felica_uart_fsync(struct file *file, struct dentry *dentry,
  3442. +                           int datasync)
  3443. +{
  3444. +   int ret;
  3445. +   struct event_struct evset = {fsync_syscall, NULL};
  3446. +   struct event_struct evset_to = {fsync_timeout_sig, NULL};
  3447. +   struct result_struct result;
  3448. +
  3449. +   pr_debug(PRT_NAME ": %s\n", __func__);
  3450. +
  3451. +   fluart->condition_fsync = 0;
  3452. +
  3453. +   result = felica_event_handle(evset);
  3454. +
  3455. +   if (-ENODATA == result.retval) {
  3456. +       pr_debug(PRT_NAME ": No data to do fsync.\n");
  3457. +       return 0;
  3458. +   } else if (0 > result.retval) {
  3459. +       pr_err(PRT_NAME ": Error. FSYNC error.\n");
  3460. +       return -EFAULT;
  3461. +   }
  3462. +
  3463. +   if (0 == fluart->condition_fsync) {
  3464. +       pr_debug(PRT_NAME ": FSYNC waiting ...\n");
  3465. +       /* Wait here until TX completes */
  3466. +       ret = wait_event_timeout(fluart->wait_fsync,
  3467. +           fluart->condition_fsync, FELICA_UART_FSYNC_TIMEOUT);
  3468. +       /* Time out case */
  3469. +       if (0 == ret) {
  3470. +           pr_err(PRT_NAME ": Error. FSYNC timeout.\n");
  3471. +           result = felica_event_handle(evset_to);
  3472. +           return -EAGAIN;
  3473. +       }
  3474. +       /* Check fsync result */
  3475. +       if (error == fluart->result_fsync) {
  3476. +           pr_err(PRT_NAME ": Error. FSYNC error.\n");
  3477. +           return -EFAULT;
  3478. +       }
  3479. +   }
  3480. +
  3481. +   pr_debug(PRT_NAME ": FSYNC succeeded.\n");
  3482. +
  3483. +   return 0;
  3484. +}
  3485. +
  3486. +/**
  3487. + * @brief   Handle IOCTL system call of FeliCa UART
  3488. + * @details This function executes;\n
  3489. + *            # Check IO control number is Available (FIONREAD).\n
  3490. + *            # Issue AVAIABLE_SYSCALL event.\n
  3491. + *            # Copy result to User space\n
  3492. + *            # [Optional][If data not increase,] sleep
  3493. + * @param   inode    : (unused)
  3494. + * @param   file     : (unused)
  3495. + * @param   cmd      : IOCTL command number
  3496. + * @param   arg      : IOCTL arguments
  3497. + * @retval  0        : Success.
  3498. + * @retval  Negative : Failure.\n
  3499. + *            -EINVAL = The arguments are invalid for Available.\n
  3500. + *            -EFAULT = RX buffer/Data copy error to execute Available.\n
  3501. + *            -ENOTTY = Unsupported IOCTL number
  3502. + */
  3503. +static int felica_uart_ioctl(struct inode *inode, struct file *file,
  3504. +               unsigned int cmd, unsigned long arg)
  3505. +{
  3506. +   int ret;
  3507. +   struct event_struct evset = {available_syscall, NULL};
  3508. +   struct result_struct result;
  3509. +
  3510. +   pr_debug(PRT_NAME ": %s\n", __func__);
  3511. +
  3512. +   if (IOCTL_UART_AVAILABLE == cmd) {
  3513. +       pr_debug(PRT_NAME ": cmd = AVAILABLE\n");
  3514. +       if (!arg) {
  3515. +           pr_err(PRT_NAME
  3516. +               ": Error. Invalid arg @available.\n");
  3517. +           return -EINVAL;
  3518. +       }
  3519. +
  3520. +       result = felica_event_handle(evset);
  3521. +       if (0 > result.retval) {
  3522. +           pr_err(PRT_NAME ": Error. RX buffer check failed.\n");
  3523. +           return -EFAULT;
  3524. +       }
  3525. +
  3526. +       ret = copy_to_user((int __user *) arg,
  3527. +                   &result.retval, sizeof(int));
  3528. +       if (ret) {
  3529. +           pr_err(PRT_NAME
  3530. +               ": Error. copy_to_user failed.\n");
  3531. +           return -EFAULT;
  3532. +       }
  3533. +       pr_debug(PRT_NAME ": Availble result = %d.\n", result.retval);
  3534. +
  3535. +       /* [Optional][If data not increase,] sleep */
  3536. +       if ((result.retval == fluart->prev_avail)
  3537. +               && (0 < FELICA_UART_AVAILABLE_MSLEEP)) {
  3538. +           pr_debug(PRT_NAME ": Available sleep(%dms).\n",
  3539. +                       FELICA_UART_AVAILABLE_MSLEEP);
  3540. +           msleep(FELICA_UART_AVAILABLE_MSLEEP);
  3541. +       }
  3542. +       fluart->prev_avail = result.retval;
  3543. +
  3544. +       return 0;
  3545. +   } else {
  3546. +       pr_err(PRT_NAME ": Error. Unsupported IOCTL.\n");
  3547. +       return -ENOTTY;
  3548. +   }
  3549. +}
  3550. +
  3551. +/***************** UART FOPS ****************************/
  3552. +static const struct file_operations felica_uart_fops = {
  3553. +   .owner      = THIS_MODULE,
  3554. +   .read       = felica_uart_read,
  3555. +   .write      = felica_uart_write,
  3556. +   .ioctl      = felica_uart_ioctl,
  3557. +   .open       = felica_uart_open,
  3558. +   .release    = felica_uart_release,
  3559. +   .fsync      = felica_uart_fsync,
  3560. +};
  3561. +
  3562. +static struct miscdevice felica_uart_device = {
  3563. +   .minor = MISC_DYNAMIC_MINOR,
  3564. +   .name = "felica",
  3565. +   .fops = &felica_uart_fops,
  3566. +};
  3567. +
  3568. +/**
  3569. + * @brief   Initialize FeliCa UART and register its device
  3570. + * @details This function executes;\n
  3571. + *            # Check UART platform data\n
  3572. + *            # Alloc and Initialize UART controller's data\n
  3573. + *            # Call UARTDM module init function\n
  3574. + *            # Call UARTMUX module init function\n
  3575. + *            # Init UART ref count\n
  3576. + *            # Create UART character device (/dev/felica)\n
  3577. + *            # State-machine initialization
  3578. + * @param   pfdata   : Pointer to UART platform data
  3579. + * @retval  0        : Success
  3580. + * @retval  Negative : Initialization failed.\n
  3581. + *            -EINVAL = No platform data\n
  3582. + *            -ENOMEM = No enough memory / Cannot create char dev.\n
  3583. + *            -EIO    = UARTDM init error.\n
  3584. + *            -ENODEV = Transition definition not exists.
  3585. + * @note
  3586. + */
  3587. +int felica_uart_probe_func(struct felica_uart_pfdata *pfdata)
  3588. +{
  3589. +   int ret;
  3590. +
  3591. +   pr_debug(PRT_NAME ": %s\n", __func__);
  3592. +
  3593. +   /* Check platform data argment */
  3594. +   if (!pfdata) {
  3595. +       pr_err(PRT_NAME ": Error. No platform data for FeliCa UART.\n");
  3596. +       ret = -EINVAL;
  3597. +       goto err_check_platform_data;
  3598. +   }
  3599. +
  3600. +   /* Alloc driver data area */
  3601. +   fluart = kzalloc(sizeof(struct felica_uart_data), GFP_KERNEL);
  3602. +   if (!fluart) {
  3603. +       pr_err(PRT_NAME ": Error. No enough mem for UART.\n");
  3604. +       ret = -ENOMEM;
  3605. +       goto err_alloc_uart_data;
  3606. +   }
  3607. +   /* Import UART platform data */
  3608. +   fluart->pfdata = pfdata;
  3609. +   /* Init wait queue */
  3610. +   init_waitqueue_head(&fluart->wait_fsync);
  3611. +   /* Set UARTDM callbacks functions */
  3612. +   pfdata->uartdm_pfdata.callback_rcv_1byte = felica_cb_rcv_1byte;
  3613. +   pfdata->uartdm_pfdata.callback_rx_complete = felica_cb_rx_complete;
  3614. +   pfdata->uartdm_pfdata.callback_rx_error = felica_cb_rx_error;
  3615. +   pfdata->uartdm_pfdata.callback_tx_complete = felica_cb_tx_complete;
  3616. +   pfdata->uartdm_pfdata.callback_tx_error = felica_cb_tx_error;
  3617. +
  3618. +   /* UARTDM module init */
  3619. +   ret = msm_uartdm_init(&pfdata->uartdm_pfdata);
  3620. +   if (ret) {
  3621. +       pr_err(PRT_NAME ": Error. UARTDM init failed.\n");
  3622. +       ret = -EIO;
  3623. +       goto err_msm_uartdm_init;
  3624. +   }
  3625. +
  3626. +   /* UARTMUX module init */
  3627. +   msm_uartmux_init();
  3628. +
  3629. +   /* Init UART ref count*/
  3630. +   fluart->refcnt = 0;
  3631. +
  3632. +   /* Crate UART character device */
  3633. +   ret = misc_register(&felica_uart_device);
  3634. +   if (ret) {
  3635. +       pr_err(PRT_NAME ": Error. Cannot register UART.\n");
  3636. +       ret = -ENOMEM;
  3637. +       goto err_create_uart_dev;
  3638. +   }
  3639. +
  3640. +   /* State machine initialization */
  3641. +   if (NULL == tran[0][0].action) {  /* Must refer to tran for build */
  3642. +       ret = -ENODEV;
  3643. +       goto err_tran_definition;
  3644. +   }
  3645. +   felica_statemachine_init();
  3646. +
  3647. +   return 0;
  3648. +
  3649. +err_tran_definition:
  3650. +   misc_deregister(&felica_uart_device);
  3651. +err_create_uart_dev:
  3652. +   msm_uartmux_exit();
  3653. +   msm_uartdm_exit();
  3654. +err_msm_uartdm_init:
  3655. +   kfree(fluart);
  3656. +err_alloc_uart_data:
  3657. +err_check_platform_data:
  3658. +   return ret;
  3659. +}
  3660. +
  3661. +/**
  3662. + * @brief   Terminate FeliCa UART controller
  3663. + * @details This function executes;\n
  3664. + *            # Issue EXEC_CLOSE_SIG for the case UART is opened\n
  3665. + *            # State-machine termination\n
  3666. + *            # Dedegister UART character device (/dev/felica)\n
  3667. + *            # Call UARTMUX module exit function\n
  3668. + *            # Call UARTDM module exit function\n
  3669. + *            # Release UART controller's data
  3670. + * @param   N/A
  3671. + * @retval  N/A
  3672. + * @note
  3673. + */
  3674. +void felica_uart_remove_func(void)
  3675. +{
  3676. +   struct event_struct evset = {exec_close_sig, NULL};
  3677. +   struct result_struct result;
  3678. +
  3679. +   pr_debug(PRT_NAME ": %s\n", __func__);
  3680. +
  3681. +   /* Forced exec_close_sig */
  3682. +   result = felica_event_handle(evset);
  3683. +
  3684. +   felica_statemachine_exit();
  3685. +   misc_deregister(&felica_uart_device);
  3686. +   msm_uartmux_exit();
  3687. +   msm_uartdm_exit();
  3688. +   kfree(fluart);
  3689. +}
  3690. diff -ruN a/4.1.B.0.431//vendor/semc/hardware/felica/felica_uart.h b/4.1.B.0.479//vendor/semc/hardware/felica/felica_uart.h
  3691. --- a/4.1.B.0.431//vendor/semc/hardware/felica/felica_uart.h    1970-01-01 09:00:00.000000000 +0900
  3692. +++ b/4.1.B.0.479//vendor/semc/hardware/felica/felica_uart.h    2012-06-25 19:30:44.000000000 +0900
  3693. @@ -0,0 +1,40 @@
  3694. +/* vendor/semc/hardware/felica/felica_uart.h
  3695. + *
  3696. + * Copyright (C) 2010 Sony Ericsson Mobile Communications AB.
  3697. + *
  3698. + * Author: Hiroaki Kuriyama <[email protected]>
  3699. + *
  3700. + * This program is free software; you can redistribute it and/or modify
  3701. + * it under the terms of the GNU General Public License version 2, as
  3702. + * published by the Free Software Foundation; either version 2
  3703. + * of the License, or (at your option) any later version.
  3704. + */
  3705. +
  3706. +#ifndef _FELICA_UART_H
  3707. +#define _FELICA_UART_H
  3708. +
  3709. +#include <linux/param.h>
  3710. +#include <asm/ioctls.h>
  3711. +
  3712. +#define FELICA_UART_FSYNC_TIMEOUT  (3 * HZ)
  3713. +#define FELICA_UART_READ_MSLEEP        1
  3714. +#define FELICA_UART_AVAILABLE_MSLEEP   1
  3715. +
  3716. +#define IOCTL_UART_AVAILABLE   FIONREAD
  3717. +
  3718. +struct felica_uart_pfdata;
  3719. +
  3720. +struct read_data_struct {
  3721. +   char __user *buf;
  3722. +   size_t count;
  3723. +};
  3724. +
  3725. +struct write_data_struct {
  3726. +   const char __user *buf;
  3727. +   size_t count;
  3728. +};
  3729. +
  3730. +int felica_uart_probe_func(struct felica_uart_pfdata *);
  3731. +void felica_uart_remove_func(void);
  3732. +
  3733. +#endif
  3734. diff -ruN a/4.1.B.0.431//vendor/semc/hardware/felica/msm_felica_cen.c b/4.1.B.0.479//vendor/semc/hardware/felica/msm_felica_cen.c
  3735. --- a/4.1.B.0.431//vendor/semc/hardware/felica/msm_felica_cen.c 1970-01-01 09:00:00.000000000 +0900
  3736. +++ b/4.1.B.0.479//vendor/semc/hardware/felica/msm_felica_cen.c 2012-06-25 19:30:44.000000000 +0900
  3737. @@ -0,0 +1,389 @@
  3738. +/* vendor/semc/hardware/felica/msm_felica_cen.c
  3739. + *
  3740. + * Copyright (C) 2010 Sony Ericsson Mobile Communications AB.
  3741. + *
  3742. + * Author: Hiroaki Kuriyama <[email protected]>
  3743. + *
  3744. + * This program is free software; you can redistribute it and/or modify
  3745. + * it under the terms of the GNU General Public License version 2, as
  3746. + * published by the Free Software Foundation; either version 2
  3747. + * of the License, or (at your option) any later version.
  3748. + */
  3749. +
  3750. +#include <linux/module.h>
  3751. +#include <linux/kernel.h>
  3752. +#include <linux/init.h>
  3753. +#include <linux/types.h>
  3754. +#include <linux/stddef.h>
  3755. +#include <linux/fs.h>
  3756. +#include <linux/miscdevice.h>
  3757. +#include <linux/mfd/pmic8058.h>
  3758. +#include <linux/pmic8058-nfc.h>
  3759. +#include <linux/delay.h>
  3760. +#include <linux/uaccess.h>
  3761. +#include "semc_felica_ext.h"
  3762. +#include "felica_cen.h"
  3763. +#include <crypto/hash.h>
  3764. +#include <linux/slab.h>
  3765. +
  3766. +#define PRT_NAME "felica cen"
  3767. +#define MON_LEVEL_IS_2P90 (0x0)
  3768. +#define MON_LEVEL_IS_2P95 (0x1)
  3769. +#define MON_LEVEL_IS_3P00 (0x2)
  3770. +#define MON_LEVEL_IS_3P05 (0x3)
  3771. +#define CEN_LOW  (0x00)
  3772. +#define CEN_HIGH (0x01)
  3773. +#define WRITE_LEN 1025
  3774. +#define AUTHENTICATION_LEN (WRITE_LEN - 1)
  3775. +#define AUTH_HASH_LEN 32
  3776. +#define HASH_ALG "sha256"
  3777. +
  3778. +struct felica_cen_data {
  3779. +   struct felica_cen_pfdata    *pfdata;
  3780. +   struct pm8058_nfc_device    *nfcdev;
  3781. +};
  3782. +
  3783. +static struct felica_cen_data *flcen;
  3784. +
  3785. +/** @brief Data of sha256 hash digest controller */
  3786. +struct sdesc {
  3787. +   struct shash_desc shash;
  3788. +   char ctx[];
  3789. +};
  3790. +
  3791. +/** @ Authentication hash value*/
  3792. +const u8 auth_hash[AUTH_HASH_LEN] = {
  3793. +   0xbf, 0x19, 0x2e, 0xaf, 0x67, 0x0c, 0x90, 0xc8,
  3794. +   0x12, 0x5f, 0xbb, 0xbc, 0x9e, 0x17, 0x23, 0x39,
  3795. +   0x69, 0x4a, 0xb7, 0xec, 0x3a, 0x9f, 0x91, 0x57,
  3796. +   0x80, 0xec, 0xb3, 0xf5, 0xfe, 0x28, 0x8f, 0x33
  3797. +};
  3798. +
  3799. +/**
  3800. + * @brief Generation of hash digest in SHA256
  3801. + * @details This function executes;\n
  3802. + * # Generate hash algorithm structure\n
  3803. + * # Generate calculate controller\n
  3804. + * # Calculation of hash digest in SHA256
  3805. + * @param  src : Source of hash
  3806. + * @param  src_len : Source of length
  3807. + * @param  out : Hash digest in SHA256
  3808. + * @retval 0 : Success
  3809. + * @retval -EFAULT : Failure
  3810. + * @note
  3811. + */
  3812. +int calc_hash(const u8 *src, int src_len, u8 *out)
  3813. +{
  3814. +   struct crypto_shash *shash;
  3815. +   struct sdesc *desc;
  3816. +   int size;
  3817. +   int ret = -EFAULT;
  3818. +
  3819. +   shash = crypto_alloc_shash(HASH_ALG, 0, CRYPTO_ALG_ASYNC);
  3820. +   if (IS_ERR(shash)) {
  3821. +       pr_err(PRT_NAME ": Error. crypto_alloc_shash.\n");
  3822. +       goto err_shash;
  3823. +   }
  3824. +
  3825. +   size = sizeof(struct shash_desc) + crypto_shash_descsize(shash);
  3826. +   desc = kmalloc(size, GFP_KERNEL);
  3827. +   if (!desc) {
  3828. +       pr_err(PRT_NAME ": Error. No enough mem for Desc.\n");
  3829. +       goto err_desc;
  3830. +   }
  3831. +
  3832. +   desc->shash.tfm = shash;
  3833. +   desc->shash.flags = 0x00;
  3834. +
  3835. +   if (crypto_shash_digest(&desc->shash, src, src_len, out)) {
  3836. +       pr_err(PRT_NAME ": Error. generate hash.\n");
  3837. +       goto err_generate;
  3838. +   }
  3839. +   ret = 0;
  3840. +
  3841. +err_generate:
  3842. +   kfree(desc);
  3843. +err_desc:
  3844. +   crypto_free_shash(shash);
  3845. +err_shash:
  3846. +   return ret;
  3847. +}
  3848. +
  3849. +/**
  3850. + * @brief   Open file operation of FeliCa CEN controller
  3851. + * @details This function executes;\n
  3852. + *            # Get PMIC8058 NFC device\n
  3853. + *            # Read NFC support register\n
  3854. + *            # [If NFC support is not enabled,] write initial value.
  3855. + * @param   inode    : (unused)
  3856. + * @param   file     : (unused)
  3857. + * @retval  0        : Success
  3858. + * @retval  Negative : Failure\n
  3859. + *            -ENODEV = Cannot find PMIC NFC device\n
  3860. + *            -EIO    = Cannot access PMIC NFC device
  3861. + * @note
  3862. + */
  3863. +static int felica_cen_open(struct inode *inode, struct file *file)
  3864. +{
  3865. +   int ret;
  3866. +   unsigned int st;
  3867. +
  3868. +   pr_debug(PRT_NAME ": %s\n", __func__);
  3869. +
  3870. +   /* Get PM8058 NFC device */
  3871. +   flcen->nfcdev = pm8058_nfc_request();
  3872. +   if (NULL == flcen->nfcdev) {
  3873. +       pr_err(PRT_NAME ": Error. PM-nfc not found.\n");
  3874. +       return -ENODEV;
  3875. +   }
  3876. +
  3877. +   /* Read NFC support register */
  3878. +   ret = pm8058_nfc_get_status(flcen->nfcdev, PM_NFC_CTRL_REQ, &st);
  3879. +   if (ret) {
  3880. +       pr_err(PRT_NAME ": Error. PM-nfc access failed.\n");
  3881. +       return -EIO;
  3882. +   }
  3883. +   pr_debug(PRT_NAME ": PM8058 NFC register = 0x%x\n", st);
  3884. +
  3885. +   /* [If NFC support is not enabled,] write initial value. */
  3886. +   if (!(st & PM_NFC_SUPPORT_EN)) {
  3887. +       ret = pm8058_nfc_config(flcen->nfcdev, PM_NFC_CTRL_REQ,
  3888. +           PM_NFC_SUPPORT_EN | PM_NFC_LDO_EN | MON_LEVEL_IS_2P95);
  3889. +       if (ret) {
  3890. +           pr_err(PRT_NAME ": Cannot enable PM-nfc.\n");
  3891. +           return -EIO;
  3892. +       }
  3893. +       pr_debug(PRT_NAME ": Successfully enabled PM-nfc.\n");
  3894. +   }
  3895. +
  3896. +   return 0;
  3897. +}
  3898. +
  3899. +/**
  3900. + * @brief  Close file operation of FeliCa CEN controller
  3901. + * @param  inode : (unused)
  3902. + * @param  file  : (unused)
  3903. + * @retval 0     : Success
  3904. + * @note
  3905. + */
  3906. +static int felica_cen_release(struct inode *inode, struct file *file)
  3907. +{
  3908. +   pr_debug(PRT_NAME ": %s\n", __func__);
  3909. +
  3910. +   return 0;
  3911. +}
  3912. +
  3913. +/**
  3914. + * @brief   Read file operation of FeliCa CEN controller
  3915. + * @details This function executes;\n
  3916. + *            # Read PMIC8058 NFC support register\n
  3917. + *            # Copy PM_NFC_EN value to user space
  3918. + * @param   file     : (unused)
  3919. + * @param   buf      : Destination of the read data
  3920. + * @param   count    : Data length must be 1
  3921. + * @param   offset   : (unused)
  3922. + * @retval  1        : Success
  3923. + * @retval  Negative : Failure\n
  3924. + *            -EINVAL = Invalid argment\n
  3925. + *            -EIO    = Cannot access PMIC NFC device\n
  3926. + *            -EFAULT = Cannot copy data to user space
  3927. + * @note
  3928. + */
  3929. +static ssize_t felica_cen_read(struct file *file, char __user *buf,
  3930. +                   size_t count, loff_t *offset)
  3931. +{
  3932. +   int ret;
  3933. +   char kbuf;
  3934. +   unsigned int st = 0x00000000;
  3935. +
  3936. +   pr_debug(PRT_NAME ": %s\n", __func__);
  3937. +
  3938. +   if (1 != count || !buf) {
  3939. +       pr_err(PRT_NAME ": Error. Invalid arg @CEN read.\n");
  3940. +       return -EINVAL;
  3941. +   }
  3942. +
  3943. +   /* Read PMIC8058 NFC support register */
  3944. +   ret = pm8058_nfc_get_status(flcen->nfcdev, PM_NFC_CTRL_REQ, &st);
  3945. +   if (ret) {
  3946. +       pr_err(PRT_NAME ": Error. PM-nfc access failed.\n");
  3947. +       return -EIO;
  3948. +   }
  3949. +   pr_debug(PRT_NAME ": PM8058 NFC register = 0x%x\n", st);
  3950. +   kbuf = (st & PM_NFC_EN) ? CEN_HIGH : CEN_LOW;
  3951. +
  3952. +   /* Copy PM_NFC_EN value to user space */
  3953. +   ret = copy_to_user(buf, &kbuf, 1);
  3954. +   if (ret) {
  3955. +       pr_err(PRT_NAME ": Error. copy_to_user failure.\n");
  3956. +       return -EFAULT;
  3957. +   }
  3958. +
  3959. +   /* 1 byte read */
  3960. +   return 1;
  3961. +}
  3962. +
  3963. +/**
  3964. + * @brief   Write file operation of FeliCa CEN controller
  3965. + * @details This function executes;\n
  3966. + *            # Carry out user authentication\n
  3967. + *            # Copy value from user space\n
  3968. + *            # Write PMIC8058 NFC support register\n
  3969. + *            # usec delay
  3970. + * @param   file     : (unused)
  3971. + * @param   buf      : Source of the written data
  3972. + * @param   count    : Data length must be WRITE_LEN.
  3973. + * @param   offset   : (unused)
  3974. + * @retval  1        : Success
  3975. + * @retval  Negative : Failure\n
  3976. + *            -EINVAL = Invalid argument\n
  3977. + *            -ENOMEM = No enough memory\n
  3978. + *            -EFAULT = Cannot copy data from user space\n
  3979. + *            -EIO    = Cannot access PMIC NFC device\n
  3980. + *            -EACCES = Permission denied
  3981. + */
  3982. +static ssize_t felica_cen_write(struct file *file, const char __user *buf,
  3983. +                   size_t count, loff_t *offset)
  3984. +{
  3985. +   int ret;
  3986. +   char kbuf;
  3987. +   unsigned int val;
  3988. +   u8 *src;
  3989. +   u8 hash[AUTH_HASH_LEN];
  3990. +
  3991. +   pr_debug(PRT_NAME ": %s\n", __func__);
  3992. +
  3993. +   if (WRITE_LEN != count  || !buf) {
  3994. +       pr_err(PRT_NAME ": Error. Invalid arg @CEN write.\n");
  3995. +       return -EINVAL;
  3996. +   }
  3997. +
  3998. +   /* Carry out user authentication */
  3999. +   src = kmalloc(AUTHENTICATION_LEN, GFP_KERNEL);
  4000. +   if (!src) {
  4001. +       pr_err(PRT_NAME ": Error. No enough mem for Auth.\n");
  4002. +       return -ENOMEM;
  4003. +   }
  4004. +   ret = copy_from_user(src, buf, AUTHENTICATION_LEN);
  4005. +   if (ret) {
  4006. +       pr_err(PRT_NAME ": Error. copy_from_user failure.\n");
  4007. +       kfree(src);
  4008. +       return -EFAULT;
  4009. +   }
  4010. +
  4011. +   if (calc_hash(src, AUTHENTICATION_LEN, hash)) {
  4012. +       pr_err(PRT_NAME ": Error. calc hash digest failure.\n");
  4013. +       kfree(src);
  4014. +       return -EACCES;
  4015. +   }
  4016. +
  4017. +   if (memcmp(auth_hash, hash, AUTH_HASH_LEN)) {
  4018. +       pr_err(PRT_NAME ": Error. invalid authentication.\n");
  4019. +       kfree(src);
  4020. +       return -EACCES;
  4021. +   }
  4022. +   kfree(src);
  4023. +
  4024. +   /* Copy value from user space */
  4025. +   ret = copy_from_user(&kbuf, &buf[AUTHENTICATION_LEN], 1);
  4026. +   if (ret) {
  4027. +       pr_err(PRT_NAME ": Error. copy_from_user failure.\n");
  4028. +       return -EFAULT;
  4029. +   }
  4030. +
  4031. +   /* Write PMIC8058 NFC support register */
  4032. +   if (CEN_LOW == kbuf)
  4033. +       val = 0x0;
  4034. +   else if (CEN_HIGH == kbuf)
  4035. +       val = PM_NFC_EN;
  4036. +   else {
  4037. +       pr_err(PRT_NAME ": Error. Invalid val @CEN write.\n");
  4038. +       return -EINVAL;
  4039. +   }
  4040. +   ret = pm8058_nfc_config(flcen->nfcdev, PM_NFC_EN, val);
  4041. +   if (ret) {
  4042. +       pr_err(PRT_NAME ": Error. Cannot write PM-nfc.\n");
  4043. +       return -EIO;
  4044. +   }
  4045. +
  4046. +   /* usec delay*/
  4047. +   udelay(UDELAY_CEN_WRITE);
  4048. +
  4049. +   /* 1 byte write */
  4050. +   return 1;
  4051. +}
  4052. +
  4053. +/***************** CEN FOPS ****************************/
  4054. +static const struct file_operations felica_cen_fops = {
  4055. +   .owner      = THIS_MODULE,
  4056. +   .read       = felica_cen_read,
  4057. +   .write      = felica_cen_write,
  4058. +   .ioctl      = NULL,
  4059. +   .open       = felica_cen_open,
  4060. +   .release    = felica_cen_release,
  4061. +   .fsync      = NULL,
  4062. +};
  4063. +
  4064. +static struct miscdevice felica_cen_device = {
  4065. +   .minor = MISC_DYNAMIC_MINOR,
  4066. +   .name = "felica_cen",
  4067. +   .fops = &felica_cen_fops,
  4068. +};
  4069. +
  4070. +/**
  4071. + * @brief   Initialize FeliCa CEN controller
  4072. + * @details This function executes;\n
  4073. + *            # Check CEN platform data\n
  4074. + *            # Alloc and Initialize CEN controller's data\n
  4075. + *            # Create CEN character device (/dev/felica_cen)
  4076. + * @param   pfdata   : Pointer to CEN platform data
  4077. + * @retval  0        : Success
  4078. + * @retval  Negative : Initialization failed.\n
  4079. + *            -EINVAL = No platform data\n
  4080. + *            -ENOMEM = No enough memory / Cannot create char dev
  4081. + * @note
  4082. + */
  4083. +int felica_cen_probe_func(struct felica_cen_pfdata *pfdata)
  4084. +{
  4085. +   pr_debug(PRT_NAME ": %s\n", __func__);
  4086. +
  4087. +   /* Check CEN platform data */
  4088. +   if (!pfdata) {
  4089. +       pr_err(PRT_NAME ": Error. No platform data for CEN.\n");
  4090. +       return -EINVAL;
  4091. +   }
  4092. +
  4093. +   /* Alloc and Initialize CEN controller's data */
  4094. +   flcen = kzalloc(sizeof(struct felica_cen_data), GFP_KERNEL);
  4095. +   if (!flcen) {
  4096. +       pr_err(PRT_NAME ": Error. No enough mem for CEN.\n");
  4097. +       return -ENOMEM;
  4098. +   }
  4099. +   flcen->pfdata = pfdata;
  4100. +
  4101. +   /* Create CEN character device (/dev/felica_cen) */
  4102. +   if (misc_register(&felica_cen_device)) {
  4103. +       pr_err(PRT_NAME ": Error. Cannot register CEN.\n");
  4104. +       kfree(flcen);
  4105. +       return -ENOMEM;
  4106. +   }
  4107. +
  4108. +   return 0;
  4109. +}
  4110. +
  4111. +/**
  4112. + * @brief   Terminate FeliCa cen controller
  4113. + * @details This function executes;\n
  4114. + *            # Deregister CEN character device (/dev/felica_cen)\n
  4115. + *            # Release CEN controller's data
  4116. + * @param   N/A
  4117. + * @retval  N/A
  4118. + * @note
  4119. + */
  4120. +void felica_cen_remove_func(void)
  4121. +{
  4122. +   pr_debug(PRT_NAME ": %s\n", __func__);
  4123. +
  4124. +   misc_deregister(&felica_cen_device);
  4125. +   kfree(flcen);
  4126. +}
  4127. diff -ruN a/4.1.B.0.431//vendor/semc/hardware/felica/msm_uartdm.c b/4.1.B.0.479//vendor/semc/hardware/felica/msm_uartdm.c
  4128. --- a/4.1.B.0.431//vendor/semc/hardware/felica/msm_uartdm.c 1970-01-01 09:00:00.000000000 +0900
  4129. +++ b/4.1.B.0.479//vendor/semc/hardware/felica/msm_uartdm.c 2012-06-25 19:30:44.000000000 +0900
  4130. @@ -0,0 +1,1009 @@
  4131. +/* vendor/semc/hardware/felica/msm_uartdm.c
  4132. + *
  4133. + * Copyright (C) 2010 Sony Ericsson Mobile Communications AB.
  4134. + *
  4135. + * Author: Hiroaki Kuriyama <[email protected]>
  4136. + *
  4137. + * This program is free software; you can redistribute it and/or modify
  4138. + * it under the terms of the GNU General Public License version 2, as
  4139. + * published by the Free Software Foundation; either version 2
  4140. + * of the License, or (at your option) any later version.
  4141. + */
  4142. +
  4143. +#include <linux/kernel.h>
  4144. +#include <linux/stddef.h>
  4145. +#include <linux/err.h>
  4146. +#include <linux/types.h>
  4147. +#include <linux/clk.h>
  4148. +#include <linux/io.h>
  4149. +#include <linux/ioport.h>
  4150. +#include <linux/workqueue.h>
  4151. +#include <linux/dma-mapping.h>
  4152. +#include <linux/interrupt.h>
  4153. +#include <mach/dma.h>
  4154. +#include "semc_felica_ext.h"
  4155. +#include "msm_uartdm.h"
  4156. +#include "msm_uartmux.h"
  4157. +#include "felica_rxbuf.h"
  4158. +#include "felica_txbuf.h"
  4159. +
  4160. +#define PRT_NAME "msm uartdm"
  4161. +#define DMOV_NON_GRACEFUL  (0)
  4162. +#define DMOV_GRACEFUL      (1)
  4163. +
  4164. +struct msm_uartdm_data {
  4165. +   /* Platform data */
  4166. +   struct msm_uartdm_pfdata    *pfdata;
  4167. +   /* Workqueue for callback */
  4168. +   struct workqueue_struct     *uartdm_wq;
  4169. +   struct work_struct  rcv_1byte_work;
  4170. +   struct work_struct  rx_end_work;
  4171. +   struct work_struct  rx_error_work;
  4172. +   struct work_struct  tx_end_work;
  4173. +   struct work_struct  tx_error_work;
  4174. +   /* IO-remap of UARTDM port */
  4175. +   char            *vaddr_uartdm;
  4176. +   struct resource     *iores_uartdm;
  4177. +   /* UARTDM clock */
  4178. +   struct clk      *clk_uartdm;
  4179. +   /* TX DMOV data */
  4180. +   struct msm_dmov_cmd txdmov_cmd;
  4181. +   dmov_box        *txbox;
  4182. +   u32         *txbox_ptr;
  4183. +   dma_addr_t      mapped_txbox;
  4184. +   dma_addr_t      mapped_txbox_ptr;
  4185. +   /* RX DMOV data */
  4186. +   struct msm_dmov_cmd rxdmov_cmd;
  4187. +   dmov_box        *rxbox;
  4188. +   u32         *rxbox_ptr;
  4189. +   dma_addr_t      mapped_rxbox;
  4190. +   dma_addr_t      mapped_rxbox_ptr;
  4191. +   /* Record of IMR registger */
  4192. +   unsigned int        imr_reg;
  4193. +   /* Record of IMR registger */
  4194. +   spinlock_t      lock;
  4195. +   /* Dummy distination for RX discard */
  4196. +   void            *dummy_dst_buf;
  4197. +   dma_addr_t      dummy_dst_dmabase;
  4198. +};
  4199. +
  4200. +static struct msm_uartdm_data *urdm;
  4201. +
  4202. +/**
  4203. + * @brief  Read function of UARTDM register
  4204. + * @param  offset : Offset from UARTDM base address
  4205. + * @retval value  : Register value (32bit)
  4206. + * @note   If offset is out of range, error message is displayed.
  4207. + *         No error returns.
  4208. + */
  4209. +static unsigned int msm_uartdm_read(unsigned int offset)
  4210. +{
  4211. +   if (UARTDM_SIZE <= offset) {
  4212. +       pr_err(PRT_NAME ": Error. msm_uartdm_read invalid offset\n");
  4213. +       return 0x0;
  4214. +   }
  4215. +   return ioread32(urdm->vaddr_uartdm + offset);
  4216. +}
  4217. +
  4218. +/**
  4219. + * @brief  Write function of UARTDM register
  4220. + * @param  offset : Offset from UARTDM base address
  4221. + * @param  value  : Register value to write (32bit)
  4222. + * @retval N/A
  4223. + * @note   If offset is out of range, error message is displayed.
  4224. + *         No error returns.
  4225. + */
  4226. +static void msm_uartdm_write(unsigned int offset, unsigned int value)
  4227. +{
  4228. +   if (UARTDM_SIZE <= offset) {
  4229. +       pr_err(PRT_NAME ": Error. msm_uartdm_write invalid offset\n");
  4230. +       return;
  4231. +   }
  4232. +   iowrite32(value, urdm->vaddr_uartdm + offset);
  4233. +}
  4234. +
  4235. +/**
  4236. + * @brief   RX DMA completiton handling
  4237. + * @details This function executes;\n
  4238. + *            # Disable RX stale interrupt\n
  4239. + *            # UARTDM command (Disable stale event)\n
  4240. + *            # UARTDM command (Reset stale event)\n
  4241. + *            # [If RX DMA succeeded,] queue work of RX end\n
  4242. + *            # [If RX DMA failed,] queue work of RX error\n
  4243. + * @param   cmd_ptr : (unused)
  4244. + * @param   result  : Result value of the DMA transfer (32bit data)
  4245. + * @param   err     : (unused)
  4246. + * @retval  N/A
  4247. + * @note
  4248. + */
  4249. +static void msm_uartdm_rxdmov_callback(struct msm_dmov_cmd *cmd_ptr,
  4250. +           unsigned int result, struct msm_dmov_errdata *err)
  4251. +{
  4252. +   pr_debug(PRT_NAME ": %s\n", __func__);
  4253. +
  4254. +   /* Disable RX Stale interrupt */
  4255. +   urdm->imr_reg &= ~BIT_RXSTALE;
  4256. +   msm_uartdm_write(UART_DM_IMR, urdm->imr_reg);
  4257. +   /* UARTDM command (Disable stale event) */
  4258. +   msm_uartdm_write(UART_DM_CR, GCMD_DISABLE_STALE_EVENT);
  4259. +   /* UARTDM command (Reset stale event) */
  4260. +   msm_uartdm_write(UART_DM_CR, CCMD_RESET_STALE_INTERRUPT);
  4261. +
  4262. +   if (result & DMOV_RSLT_ERROR)
  4263. +       /* Queue work of RX end */
  4264. +       queue_work(urdm->uartdm_wq, &urdm->rx_error_work);
  4265. +   else
  4266. +       /* Queue work of RX error */
  4267. +       queue_work(urdm->uartdm_wq, &urdm->rx_end_work);
  4268. +}
  4269. +
  4270. +/**
  4271. + * @brief   TX DMOV completiton handling
  4272. + * @details This function executes;\n
  4273. + *            # [If TX DMA succeeded,] enable TX ready interrupt.\n
  4274. + *            # [If TX DMA failed,] queue work of TX error\n
  4275. + * @param   cmd_ptr : (unused)
  4276. + * @param   result  : Result value of the DMA transfer (32bit data)
  4277. + * @param   err     : (unused)
  4278. + * @retval  N/A
  4279. + */
  4280. +static void msm_uartdm_txdmov_callback(struct msm_dmov_cmd *cmd_ptr,
  4281. +           unsigned int result, struct msm_dmov_errdata *err)
  4282. +{
  4283. +   pr_debug(PRT_NAME ": %s\n", __func__);
  4284. +
  4285. +   if (result & DMOV_RSLT_ERROR) {
  4286. +       queue_work(urdm->uartdm_wq, &urdm->tx_error_work);
  4287. +   } else {
  4288. +       urdm->imr_reg |= BIT_TX_READY;
  4289. +       msm_uartdm_write(UART_DM_IMR, urdm->imr_reg);
  4290. +   }
  4291. +}
  4292. +
  4293. +/**
  4294. + * @brief   RX DMOV reset
  4295. + * @details This function executes;\n
  4296. + *            # Order RX graceful flush of DMA
  4297. + * @param   N/A
  4298. + * @retval  N/A
  4299. + * @note    If no active RX-DMA command, msm_dmov_flush() does nothing.
  4300. + */
  4301. +static void msm_uartdm_rxdmov_reset(void)
  4302. +{
  4303. +   pr_debug(PRT_NAME ": %s\n", __func__);
  4304. +
  4305. +   msm_dmov_flush(urdm->pfdata->chan_uartdm_rx);
  4306. +}
  4307. +
  4308. +/**
  4309. + * @brief   IRQ handler of MSM UARTDM
  4310. + * @details This function executes;\n
  4311. + *          [If ISR == RXLEV,]\n
  4312. + *            # Disable RXLEV interrupt\n
  4313. + *            # Queue work of 1byte reception\n
  4314. + *          [If ISR == RX stale,]\n
  4315. + *            # Disable RX stale interrupt\n
  4316. + *            # Order RX graceful flush of DMA\n
  4317. + *          [If ISR == TX ready,]\n
  4318. + *            # Disable TX ready interrupt\n
  4319. + *            # Reset command of TX ready\n
  4320. + *            # Queue work of TX end
  4321. + * @param   irq : (unused)
  4322. + * @param   dev : (unused)
  4323. + * @retval  IRQ_HANDLED : Success. IRQ handled.
  4324. + * @retval  IRQ_NONE    : Failure. Unknown IRQ reason.
  4325. + * @note
  4326. + */
  4327. +static irqreturn_t msm_uartdm_irq_handler(int irq, void *dev)
  4328. +{
  4329. +   unsigned int isr_reg;
  4330. +   unsigned long flags;
  4331. +
  4332. +   pr_debug(PRT_NAME ": %s\n", __func__);
  4333. +
  4334. +   spin_lock_irqsave(&urdm->lock, flags);
  4335. +
  4336. +   isr_reg = msm_uartdm_read(UART_DM_ISR);
  4337. +
  4338. +   pr_debug(PRT_NAME ": IMR = 0x%x, ISR =0x%x\n", urdm->imr_reg, isr_reg);
  4339. +
  4340. +   /* RXLEV (1byte recognition)*/
  4341. +   if (urdm->imr_reg & isr_reg & BIT_RXLEV) {
  4342. +       urdm->imr_reg &= ~BIT_RXLEV;
  4343. +       msm_uartdm_write(UART_DM_IMR, urdm->imr_reg);
  4344. +       queue_work(urdm->uartdm_wq, &urdm->rcv_1byte_work);
  4345. +       pr_debug(PRT_NAME ": RX lev -> Rcv 1byte callback.\n");
  4346. +   }
  4347. +   /* RX Stale (RXDM timeout)*/
  4348. +   else if (urdm->imr_reg & isr_reg & BIT_RXSTALE) {
  4349. +       urdm->imr_reg &= ~BIT_RXSTALE;
  4350. +       msm_uartdm_write(UART_DM_IMR, urdm->imr_reg);
  4351. +       msm_dmov_flush(urdm->pfdata->chan_uartdm_rx);
  4352. +       pr_debug(PRT_NAME ": RX stale -> Graceful flush.\n");
  4353. +   }
  4354. +   /* TX Ready (TX completion) */
  4355. +   else if (urdm->imr_reg & isr_reg & BIT_TX_READY) {
  4356. +       urdm->imr_reg &= ~BIT_TX_READY;
  4357. +       msm_uartdm_write(UART_DM_IMR, urdm->imr_reg);
  4358. +       msm_uartdm_write(UART_DM_CR, GCMD_RESET_TX_READY_INTERRUPT);
  4359. +       queue_work(urdm->uartdm_wq, &urdm->tx_end_work);
  4360. +       pr_debug(PRT_NAME ": TX ready.\n");
  4361. +   }
  4362. +   /* Unknown IRQ reason */
  4363. +   else {
  4364. +       spin_unlock_irqrestore(&urdm->lock, flags);
  4365. +       return IRQ_NONE;
  4366. +   }
  4367. +
  4368. +   spin_unlock_irqrestore(&urdm->lock, flags);
  4369. +
  4370. +   return IRQ_HANDLED;
  4371. +}
  4372. +
  4373. +/**
  4374. + * @brief   Start MSM UARTDM RX transfer
  4375. + * @details This function executes;\n
  4376. + *            # Check UARTDM port\n
  4377. + *            # Check UARTDM RX overrun\n
  4378. + *            # Direct RX DMA path\n
  4379. + *            # Enable RX Stale IRQ\n
  4380. + *            # UARTDM command (Enable stale event)\n
  4381. + *            # Enqueue RX DMA command\n
  4382. + *            # Write DMRX register
  4383. + * @param   N/A
  4384. + * @retval  0        : Success
  4385. + * @retval  Negative : Failure\n
  4386. + *            -ENODEV = UARTDM not opened.\n
  4387. + *            -EIO    = UARTDM RX overrun
  4388. + */
  4389. +int msm_uartdm_rx_start(void)
  4390. +{
  4391. +   unsigned int sr;
  4392. +
  4393. +   pr_debug(PRT_NAME ": %s\n", __func__);
  4394. +
  4395. +   /* Check UARTDM port */
  4396. +   if (!urdm->vaddr_uartdm) {
  4397. +       pr_err(PRT_NAME ": Error. UARTDM not opened.\n");
  4398. +       return -ENODEV;
  4399. +   }
  4400. +
  4401. +   /* Check UARTDM RX overrun */
  4402. +   sr = msm_uartdm_read(UART_DM_SR);
  4403. +   if (sr & BIT_UART_OVERRUN) {
  4404. +       pr_err(PRT_NAME ": Warning. UART RX overran.\n");
  4405. +       msm_uartdm_write(UART_DM_CR, CCMD_RESET_ERROR_STATUS);
  4406. +       return -EIO;
  4407. +   }
  4408. +
  4409. +   /* Direct RX DMA path */
  4410. +   urdm->rxbox->dst_row_addr = felica_rxbuf_push_pointer();
  4411. +   if (urdm->rxbox->dst_row_addr) {
  4412. +       urdm->rxbox->row_offset = UARTDM_BURST_SIZE;
  4413. +   } else {
  4414. +       urdm->rxbox->dst_row_addr = urdm->dummy_dst_dmabase;
  4415. +       urdm->rxbox->row_offset = 0x0;
  4416. +   }
  4417. +
  4418. +   /* Enable RX Stale IRQ */
  4419. +   urdm->imr_reg |= BIT_RXSTALE;
  4420. +   msm_uartdm_write(UART_DM_IMR, urdm->imr_reg);
  4421. +
  4422. +   /* UARTDM command (Enable stale event) */
  4423. +   msm_uartdm_write(UART_DM_CR, GCMD_ENABLE_STALE_EVENT);
  4424. +
  4425. +   /* Enqueue RX DMA command */
  4426. +   msm_dmov_enqueue_cmd(urdm->pfdata->chan_uartdm_rx, &urdm->rxdmov_cmd);
  4427. +
  4428. +   /* Write DMRX register */
  4429. +   msm_uartdm_write(UART_DM_DMRX, LOCAL_UARTDM_RX_FIFO_SIZE);
  4430. +
  4431. +   return 0;
  4432. +}
  4433. +
  4434. +/**
  4435. + * @brief   Reset MSM UARTDM RX port
  4436. + * @details This function executes;\n
  4437. + *            # Check UARTDM port\n
  4438. + *            # UARTDM command (Disable UARTDM RX)\n
  4439. + *            # UARTDM command (Reset UARTDM RX)\n
  4440. + *            # UARTDM command (Reset Error&Stale)\n
  4441. + *            # Clear RX buffer\n
  4442. + *            # Call RX DMA reset\n
  4443. + *            # UARTDM command (Enable UARTDM RX)
  4444. + * @param   N/A
  4445. + * @retval  0        : Success
  4446. + * @retval  Negative : Failure\n
  4447. + *            -ENODEV = UARTDM not opened.
  4448. + * @note
  4449. + */
  4450. +int msm_uartdm_rx_reset(void)
  4451. +{
  4452. +
  4453. +   pr_debug(PRT_NAME ": %s\n", __func__);
  4454. +
  4455. +   /* Check UARTDM port */
  4456. +   if (!urdm->vaddr_uartdm) {
  4457. +       pr_err(PRT_NAME ": Error. UARTDM not opened.\n");
  4458. +       return -ENODEV;
  4459. +   }
  4460. +
  4461. +   msm_uartdm_write(UART_DM_CR, BIT_UART_RX_DISABLE);
  4462. +   msm_uartdm_write(UART_DM_CR, CCMD_RESET_RECEIVER);
  4463. +   msm_uartdm_write(UART_DM_CR, CCMD_RESET_ERROR_STATUS);
  4464. +   msm_uartdm_write(UART_DM_CR, CCMD_RESET_STALE_INTERRUPT);
  4465. +   felica_rxbuf_clear();
  4466. +   msm_uartdm_rxdmov_reset();
  4467. +   msm_uartdm_write(UART_DM_CR, BIT_UART_RX_EN);
  4468. +
  4469. +   return 0;
  4470. +}
  4471. +
  4472. +
  4473. +/**
  4474. + * @brief   Start MSM UARTDM TX transfer
  4475. + * @details This function executes;\n
  4476. + *            # Check UARTDM port\n
  4477. + *            # Count data in TX buffer\n
  4478. + *            # Get TX buffer pointer\n
  4479. + *            # Update TX buffer information
  4480. + *            # Enqueue TX DMA command\n
  4481. + *            # Write NO_CHARS_FOR_TX register\n
  4482. + * @param   N/A
  4483. + * @retval  0        : Success
  4484. + * @retval  Negative : Failure.\n
  4485. + *            -ENODEV  = UARTDM not opened / Cannot access TX buf\n
  4486. + *            -EFAULT  = Cannot update TX buf\n
  4487. + *            -ENODATA = No TX data exists.
  4488. + * @note
  4489. + */
  4490. +int msm_uartdm_tx_start(void)
  4491. +{
  4492. +   int cnt, ret;
  4493. +
  4494. +   pr_debug(PRT_NAME ": %s\n", __func__);
  4495. +
  4496. +   /* Check UARTDM port */
  4497. +   if (!urdm->vaddr_uartdm) {
  4498. +       pr_err(PRT_NAME ": Error. UARTDM not opened.\n");
  4499. +       return -ENODEV;
  4500. +   }
  4501. +
  4502. +   /* Count data in TX buffer */
  4503. +   cnt = felica_txbuf_count();
  4504. +
  4505. +   if (!cnt) {
  4506. +       pr_err(PRT_NAME ": Error. No TX data exists.\n");
  4507. +       return -ENODATA;
  4508. +   } else if (0 < cnt) {
  4509. +       /* Get TX buf pointer */
  4510. +       urdm->txbox->src_row_addr = felica_txbuf_pull_pointer();
  4511. +       urdm->txbox->num_rows = (((cnt + 15) >> 4) << 16)
  4512. +                       | ((cnt + 15) >> 4);
  4513. +       /* Update TX buffer information */
  4514. +       ret = felica_txbuf_pull_status_update(cnt);
  4515. +       if (ret) {
  4516. +           pr_err(PRT_NAME ": Error. Cannot update TX buf.\n");
  4517. +           return -EFAULT;
  4518. +       }
  4519. +       /* Enqueue TX DMA command */
  4520. +       msm_dmov_enqueue_cmd(urdm->pfdata->chan_uartdm_tx,
  4521. +                       &urdm->txdmov_cmd);
  4522. +       /* Write NO_CHAR_FOR_TX register */
  4523. +       msm_uartdm_write(UART_DM_NO_CHARS_FOR_TX, cnt);
  4524. +   } else {
  4525. +       pr_err(PRT_NAME ": Error. Cannot access TX buf.\n");
  4526. +       return -ENODEV;
  4527. +   }
  4528. +
  4529. +   return 0;
  4530. +}
  4531. +
  4532. +/**
  4533. + * @brief   Reset MSM UARTDM TX port
  4534. + * @details This function executes;\n
  4535. + *            # Check UARTDM port\n
  4536. + *            # UARTDM command (Disable UARTDM TX)\n
  4537. + *            # UARTDM command (Reset UARTDM TX)\n
  4538. + *            # UARTDM command (Reset Error)\n
  4539. + *            # Clear TX buffer\n
  4540. + *            # UARTDM command (Enable UARTDM TX)
  4541. + * @param   N/A
  4542. + * @retval  0        : Success
  4543. + * @retval  Negative : Failure\n
  4544. + *            -ENODEV = UARTDM not opened.
  4545. + */
  4546. +int msm_uartdm_tx_reset(void)
  4547. +{
  4548. +   pr_debug(PRT_NAME ": %s\n", __func__);
  4549. +
  4550. +   /* Check UARTDM port */
  4551. +   if (!urdm->vaddr_uartdm) {
  4552. +       pr_err(PRT_NAME ": Error. UARTDM not opened.\n");
  4553. +       return -ENODEV;
  4554. +   }
  4555. +
  4556. +   msm_uartdm_write(UART_DM_CR, BIT_UART_TX_DISABLE);
  4557. +   msm_uartdm_write(UART_DM_CR, CCMD_RESET_TRANSMITTER);
  4558. +   msm_uartdm_write(UART_DM_CR, CCMD_RESET_ERROR_STATUS);
  4559. +   felica_txbuf_clear();
  4560. +   msm_uartdm_write(UART_DM_CR, BIT_UART_TX_EN);
  4561. +
  4562. +   return 0;
  4563. +}
  4564. +
  4565. +/**
  4566. + * @brief   Enable interrupt of 1byte reception (RXLEV)
  4567. + * @details This function executes;\n
  4568. + *            # Check UARTDM port\n
  4569. + *            # Enable UARTDM RXLEV IRQ
  4570. + * @param   N/A
  4571. + * @retval  0 : Success
  4572. + * @retval  Negative : Failure\n
  4573. + *            -ENODEV = UARTDM not opened.
  4574. + * @note
  4575. + */
  4576. +int msm_uartdm_rcv_1byte_enable(void)
  4577. +{
  4578. +   pr_debug(PRT_NAME ": %s\n", __func__);
  4579. +
  4580. +   /* Check UARTDM port */
  4581. +   if (!urdm->vaddr_uartdm) {
  4582. +       pr_err(PRT_NAME ": Error. UARTDM not opened.\n");
  4583. +       return -ENODEV;
  4584. +   }
  4585. +
  4586. +   urdm->imr_reg |= BIT_RXLEV;
  4587. +   msm_uartdm_write(UART_DM_IMR, urdm->imr_reg);
  4588. +
  4589. +   return 0;
  4590. +}
  4591. +
  4592. +/**
  4593. + * @brief   Disable interrupt of 1byte reception (RXLEV)
  4594. + * @details This function executes;\n
  4595. + *            # Check UARTDM port\n
  4596. + *            # Disable UARTDM RXLEV IRQ
  4597. + * @param   N/A
  4598. + * @retval  0 : Success
  4599. + * @retval  Negative : Failure\n
  4600. + *            -ENODEV = UARTDM not opened.
  4601. + * @note
  4602. + */
  4603. +int msm_uartdm_rcv_1byte_disable(void)
  4604. +{
  4605. +   pr_debug(PRT_NAME ": %s\n", __func__);
  4606. +
  4607. +   /* Check UARTDM port */
  4608. +   if (!urdm->vaddr_uartdm) {
  4609. +       pr_err(PRT_NAME ": Error. UARTDM not opened.\n");
  4610. +       return -ENODEV;
  4611. +   }
  4612. +
  4613. +   urdm->imr_reg &= ~BIT_RXLEV;
  4614. +   msm_uartdm_write(UART_DM_IMR, urdm->imr_reg);
  4615. +
  4616. +   return 0;
  4617. +}
  4618. +
  4619. +/**
  4620. + * @brief   Check data length in UARTDM RX FIFO
  4621. + * @details This function executes;\n
  4622. + *            # Check UARTDM port\n
  4623. + *            # Read UARTDM SR & DMRX register
  4624. + * @param   N/A
  4625. + * @retval  0/Positive : Success. Length of data in RX FIFO.
  4626. + * @retval  Negative   : Failure\n
  4627. + *            -ENODEV = UARTDM not opened.
  4628. + * @note
  4629. + */
  4630. +int msm_uartdm_rcv_byte_check(void)
  4631. +{
  4632. +   pr_debug(PRT_NAME ": %s\n", __func__);
  4633. +
  4634. +   /* Check UARTDM port */
  4635. +   if (!urdm->vaddr_uartdm) {
  4636. +       pr_err(PRT_NAME ": Error. UARTDM not opened.\n");
  4637. +       return -ENODEV;
  4638. +   }
  4639. +
  4640. +   if (!(msm_uartdm_read(UART_DM_SR) & BIT_RXRDY))
  4641. +       return 0;
  4642. +
  4643. +   return (int) msm_uartdm_read(UART_DM_DMRX) & BIT_RX_DM_CRCI_CHARS;
  4644. +}
  4645. +
  4646. +/**
  4647. + * @brief   Work function of RX 1byte reception
  4648. + * @details This function executes;\n
  4649. + *            # If registered, call the callback function.
  4650. + * @param   work : (unused)
  4651. + * @retval  N/A
  4652. + * @note
  4653. + */
  4654. +static void msm_uartdm_rcv_1byte_work(struct work_struct *work)
  4655. +{
  4656. +   pr_debug(PRT_NAME ": %s\n", __func__);
  4657. +
  4658. +   if (urdm->pfdata->callback_rcv_1byte)
  4659. +       urdm->pfdata->callback_rcv_1byte();
  4660. +}
  4661. +
  4662. +/**
  4663. + * @brief   Work function of UARTDM RX End
  4664. + * @details This function executes;\n
  4665. + *            # [If UART opened,] check RX_TOTAL_BYTE register.\n
  4666. + *            # [If UART opened,] update RX buffer with the data length.\n
  4667. + *            # [If registered,]  call the callback function.
  4668. + * @param   work : (unused)
  4669. + * @retval  N/A
  4670. + * @note
  4671. + */
  4672. +static void msm_uartdm_rx_end_work(struct work_struct *work)
  4673. +{
  4674. +   unsigned int cnt;
  4675. +
  4676. +   pr_debug(PRT_NAME ": %s\n", __func__);
  4677. +
  4678. +   if (urdm->vaddr_uartdm) {
  4679. +       cnt = msm_uartdm_read(UART_DM_RX_TOTAL_SNAP)
  4680. +                       & BIT_RX_TOTAL_BYTES;
  4681. +       pr_debug(PRT_NAME ": RX_TOTAL_SNAP = %d\n", cnt);
  4682. +       felica_rxbuf_push_status_update(cnt);
  4683. +   } else
  4684. +       pr_warning(PRT_NAME ": Warning. rx_end_work @ UART closed.\n");
  4685. +
  4686. +   if (urdm->pfdata->callback_rx_complete)
  4687. +       urdm->pfdata->callback_rx_complete();
  4688. +}
  4689. +
  4690. +/**
  4691. + * @brief   Work function of UARTDM RX Error
  4692. + * @details This function executes;\n
  4693. + *            # If registered, call the callback function.
  4694. + * @param   work : (unused)
  4695. + * @retval  N/A
  4696. + */
  4697. +static void msm_uartdm_rx_error_work(struct work_struct *work)
  4698. +{
  4699. +   pr_debug(PRT_NAME ": %s\n", __func__);
  4700. +
  4701. +   if (urdm->pfdata->callback_rx_error)
  4702. +       urdm->pfdata->callback_rx_error();
  4703. +}
  4704. +
  4705. +/**
  4706. + * @brief   Work function of UARTDM TX End
  4707. + * @details This function executes;\n
  4708. + *            # If registered, call the callback function.
  4709. + * @param   work : (unused)
  4710. + * @retval  N/A
  4711. + * @note
  4712. + */
  4713. +static void msm_uartdm_tx_end_work(struct work_struct *work)
  4714. +{
  4715. +   pr_debug(PRT_NAME ": %s\n", __func__);
  4716. +
  4717. +   if (urdm->pfdata->callback_tx_complete)
  4718. +       urdm->pfdata->callback_tx_complete();
  4719. +}
  4720. +
  4721. +/**
  4722. + * @brief   Work function of UARTDM TX Error
  4723. + * @details This function executes;\n
  4724. + *            # If registered, call the callback function.
  4725. + * @param   work : (unused)
  4726. + * @retval  N/A
  4727. + * @note
  4728. + */
  4729. +static void msm_uartdm_tx_error_work(struct work_struct *work)
  4730. +{
  4731. +   pr_debug(PRT_NAME ": %s\n", __func__);
  4732. +
  4733. +   if (urdm->pfdata->callback_tx_error)
  4734. +       urdm->pfdata->callback_tx_error();
  4735. +}
  4736. +
  4737. +/**
  4738. + * @brief   Open MSM UARTDM port
  4739. + * @details This function executes;\n
  4740. + *            # Check UARTDM sub-module data\n
  4741. + *            # UARTDM IRQ registration\n
  4742. + *            # UARTDM MIMO remap\n
  4743. + *            # Start UARTDM clock \n
  4744. + *            # UARTDM register setting\n
  4745. + *            # UARTDM command (Cmd reg protection)\n
  4746. + *            # UARTDM command (Reset RX & TX)\n
  4747. + *            # UARTDM command (Reset Error & Stale)\n
  4748. + *            # UARTDM command (Enable RX & TX)\n
  4749. + *            # Clear TX & RX buffer\n
  4750. + *            # Init DMA command boxes (TX)\n
  4751. + *            # Init DMA command boxes (RX)\n
  4752. + * @param   N/A
  4753. + * @retval  0        : Success
  4754. + * @retval  Negative : Failure\n
  4755. + *            -ENODEV = UARTDM not initialized / Request IRQ error /
  4756. + *                      Clock cannot be configured.\n
  4757. + *            -ENOMEM = UARTDM MMIO remap error
  4758. + */
  4759. +int msm_uartdm_open(void)
  4760. +{
  4761. +   int ret;
  4762. +
  4763. +   pr_debug(PRT_NAME ": %s\n", __func__);
  4764. +
  4765. +   /* Check UARTDM sub-module data */
  4766. +   if (!urdm) {
  4767. +       pr_err(PRT_NAME ": Error. UARTDM not initialized.\n");
  4768. +       return -ENODEV;
  4769. +   }
  4770. +
  4771. +   /* UARTDM IRQ registration */
  4772. +   ret = request_irq(urdm->pfdata->irq_uartdm, msm_uartdm_irq_handler,
  4773. +     IRQF_TRIGGER_HIGH, urdm->pfdata->irq_name, urdm->pfdata->clk_dev);
  4774. +   if (ret) {
  4775. +       pr_err(PRT_NAME ": Error. Request IRQ failed.\n");
  4776. +       ret = -ENODEV;
  4777. +       goto err_request_irq_uart;
  4778. +   }
  4779. +   urdm->imr_reg = 0x0;
  4780. +
  4781. +   /* UARTDM MMIO remap */
  4782. +   urdm->iores_uartdm = request_mem_region(
  4783. +       (resource_size_t) urdm->pfdata->paddr_uartdm, UARTDM_SIZE,
  4784. +                        urdm->pfdata->iomem_name);
  4785. +   if (!urdm->iores_uartdm)
  4786. +       pr_warning(PRT_NAME ": Warning. UARTDM IOMEM conflict.\n");
  4787. +   urdm->vaddr_uartdm = ioremap_nocache(
  4788. +       (unsigned long) urdm->pfdata->paddr_uartdm, UARTDM_SIZE);
  4789. +   if (!urdm->vaddr_uartdm) {
  4790. +       pr_err(PRT_NAME ": Error. UARTDM IOremap failed.\n");
  4791. +       ret = -ENOMEM;
  4792. +       goto err_ioremap_uartdm;
  4793. +   }
  4794. +   pr_debug(PRT_NAME ": IOremap v-add 0x%x\n",
  4795. +                       (int) urdm->vaddr_uartdm);
  4796. +
  4797. +   /* Start UARTDM clock */
  4798. +   ret = clk_set_rate(urdm->clk_uartdm, LOCAL_UARTDM_BASE_FREQ);
  4799. +   ret |= clk_enable(urdm->clk_uartdm);
  4800. +   if (ret) {
  4801. +       pr_err(PRT_NAME ": Error. UARTDM clock failed.\n");
  4802. +       ret = -ENODEV;
  4803. +       goto err_uartdm_clk_enable;
  4804. +   }
  4805. +
  4806. +   /* UARTDM register setting */
  4807. +   /* + Baudrate setting */
  4808. +   msm_uartdm_write(UART_DM_CSR, LOCAL_UARTDM_BAUDRATE_CSR);
  4809. +   /* + Data-stop-parity setting (MR2) */
  4810. +   msm_uartdm_write(UART_DM_MR2, LOCAL_UARTDM_DATA_STOP_PARITY);
  4811. +   /* + UARTDM RX-TX buffer split setting */
  4812. +   msm_uartdm_write(UART_DM_BADR, LOCAL_UARTDM_TX_RX_FIFO_SPLIT);
  4813. +   /* + RX&TX wartermark setting */
  4814. +   msm_uartdm_write(UART_DM_TFWR, 0x0);
  4815. +   msm_uartdm_write(UART_DM_RFWR, 0x0);
  4816. +   /* + Stale time-out setting */
  4817. +   msm_uartdm_write(UART_DM_IPR,
  4818. +       (LOCAL_UARTDM_STALE_TIMEOUT & BIT_STALE_TIMEOUT_LSB) |
  4819. +       ((LOCAL_UARTDM_STALE_TIMEOUT << 2) & BIT_STALE_TIMEOUT_MSB));
  4820. +   /* + Enable TXDM and RXDM mode */
  4821. +   msm_uartdm_write(UART_DM_DMEN, BIT_RX_DM_EN | BIT_TX_DM_EN);
  4822. +   /* + Disable IrDA mode */
  4823. +   msm_uartdm_write(UART_DM_IRDA, 0x0);
  4824. +
  4825. +   /* UARTDM command (Cmd reg protection) */
  4826. +   msm_uartdm_write(UART_DM_CR, GCMD_CR_PROTECTION_ENABLE);
  4827. +
  4828. +   /* UARTDM command (Reset RX & TX) */
  4829. +   msm_uartdm_write(UART_DM_CR, CCMD_RESET_RECEIVER);
  4830. +   msm_uartdm_write(UART_DM_CR, CCMD_RESET_TRANSMITTER);
  4831. +
  4832. +   /* UARTDM command (Reset Error & Stale) */
  4833. +   msm_uartdm_write(UART_DM_CR, CCMD_RESET_ERROR_STATUS);
  4834. +   msm_uartdm_write(UART_DM_CR, CCMD_RESET_STALE_INTERRUPT);
  4835. +
  4836. +   /* UARTDM command (Enable RX & TX) */
  4837. +   msm_uartdm_write(UART_DM_CR, BIT_UART_TX_EN);
  4838. +   msm_uartdm_write(UART_DM_CR, BIT_UART_RX_EN);
  4839. +
  4840. +   /* Clear TX & RX buffer */
  4841. +   felica_txbuf_clear();
  4842. +   felica_rxbuf_clear();
  4843. +
  4844. +   /* Init DMA command boxes (TX) */
  4845. +   /* + TX DMOV mapping */
  4846. +   *urdm->txbox_ptr = CMD_PTR_LP | DMOV_CMD_ADDR(urdm->mapped_txbox);
  4847. +   urdm->txdmov_cmd.cmdptr = DMOV_CMD_ADDR(urdm->mapped_txbox_ptr);
  4848. +   urdm->txdmov_cmd.complete_func = msm_uartdm_txdmov_callback;
  4849. +   urdm->txdmov_cmd.cmdptr = DMOV_CMD_ADDR(urdm->mapped_txbox_ptr);
  4850. +   urdm->txbox->cmd = CMD_LC | CMD_DST_CRCI(urdm->pfdata->crci_uartdm_tx)
  4851. +                           | CMD_MODE_BOX;
  4852. +   /* + TX DMOV BOX command */
  4853. +   urdm->txbox->src_row_addr = 0x0;
  4854. +   urdm->txbox->dst_row_addr = (u32) urdm->pfdata->paddr_uartdm
  4855. +                               + UART_DM_TF;
  4856. +   urdm->txbox->src_dst_len = (UARTDM_BURST_SIZE << 16)
  4857. +                           | UARTDM_BURST_SIZE;
  4858. +   urdm->txbox->num_rows = 0x0;
  4859. +   urdm->txbox->row_offset = (UARTDM_BURST_SIZE << 16);
  4860. +
  4861. +   /* Init DMA command boxes (RX) */
  4862. +   /* + RX DMOV mapping */
  4863. +   *urdm->rxbox_ptr = CMD_PTR_LP | DMOV_CMD_ADDR(urdm->mapped_rxbox);
  4864. +   urdm->rxdmov_cmd.cmdptr = DMOV_CMD_ADDR(urdm->mapped_rxbox_ptr);
  4865. +   urdm->rxdmov_cmd.complete_func = msm_uartdm_rxdmov_callback;
  4866. +   urdm->rxdmov_cmd.cmdptr = DMOV_CMD_ADDR(urdm->mapped_rxbox_ptr);
  4867. +   urdm->rxbox->cmd = CMD_LC | CMD_SRC_CRCI(urdm->pfdata->crci_uartdm_rx)
  4868. +                           | CMD_MODE_BOX;
  4869. +   /* + RX DMOV BOX command */
  4870. +   urdm->rxbox->src_row_addr = (u32) urdm->pfdata->paddr_uartdm
  4871. +                           + UART_DM_RF;
  4872. +   urdm->rxbox->dst_row_addr = 0x0;    /* Will be set later */
  4873. +   urdm->rxbox->src_dst_len = (UARTDM_BURST_SIZE << 16)
  4874. +                       | UARTDM_BURST_SIZE;
  4875. +   urdm->rxbox->num_rows = ((LOCAL_UARTDM_RX_FIFO_SIZE >> 4) << 16)
  4876. +                   | (LOCAL_UARTDM_RX_FIFO_SIZE >> 4);
  4877. +   urdm->rxbox->row_offset = 0x0;      /* Will be set later */
  4878. +
  4879. +   return 0;
  4880. +
  4881. +err_uartdm_clk_enable:
  4882. +   iounmap(urdm->vaddr_uartdm);
  4883. +   urdm->vaddr_uartdm = NULL;
  4884. +   if (urdm->iores_uartdm)
  4885. +       release_mem_region((u32) urdm->pfdata->paddr_uartdm,
  4886. +                           UARTDM_SIZE);
  4887. +err_ioremap_uartdm:
  4888. +   free_irq(urdm->pfdata->irq_uartdm, urdm->pfdata->clk_dev);
  4889. +err_request_irq_uart:
  4890. +   return ret;
  4891. +}
  4892. +
  4893. +/**
  4894. + * @brief   Close MSM UARTDM port
  4895. + * @details This function executes;\n
  4896. + *            # Check UARTDM port\n
  4897. + *            # Reset RX DMA\n
  4898. + *            # Clear TX & RX buffer\n
  4899. + *            # UARTDM command (Disable RX & TX)\n
  4900. + *            # UARTDM command (Reset Error & Stale)\n
  4901. + *            # UARTDM command (Reset RX & TX)\n
  4902. + *            # Stop UARTDM clock\n
  4903. + *            # Release MIMO resource\n
  4904. + *            # Release UARTDM IRQ
  4905. + * @param   N/A
  4906. + * @retval  0        : Success
  4907. + * @retval  Negative : Failure\n
  4908. + *            -ENODEV = UARTDM not opened.
  4909. + * @note
  4910. + */
  4911. +int msm_uartdm_close(void)
  4912. +{
  4913. +   pr_debug(PRT_NAME ": %s\n", __func__);
  4914. +
  4915. +   /* Check UARTDM port */
  4916. +   if (!urdm->vaddr_uartdm) {
  4917. +       pr_err(PRT_NAME ": Error. UARTDM not opened.\n");
  4918. +       return -ENODEV;
  4919. +   }
  4920. +
  4921. +   /* Reset RX DMA */
  4922. +   msm_uartdm_rxdmov_reset();
  4923. +
  4924. +   /* Clear TX & RX buffer */
  4925. +   felica_txbuf_clear();
  4926. +   felica_rxbuf_clear();
  4927. +
  4928. +   /* UARTDM command (Disable RX & TX) */
  4929. +   msm_uartdm_write(UART_DM_CR, BIT_UART_TX_DISABLE);
  4930. +   msm_uartdm_write(UART_DM_CR, BIT_UART_RX_DISABLE);
  4931. +
  4932. +   /* UARTDM command (Reset Error & Stale) */
  4933. +   msm_uartdm_write(UART_DM_CR, CCMD_RESET_ERROR_STATUS);
  4934. +   msm_uartdm_write(UART_DM_CR, CCMD_RESET_STALE_INTERRUPT);
  4935. +
  4936. +   /* UARTDM command (Reset RX & TX) */
  4937. +   msm_uartdm_write(UART_DM_CR, CCMD_RESET_RECEIVER);
  4938. +   msm_uartdm_write(UART_DM_CR, CCMD_RESET_TRANSMITTER);
  4939. +
  4940. +   /* Stop UARTDM clock */
  4941. +   clk_disable(urdm->clk_uartdm);
  4942. +
  4943. +   /* Release MIMO resource */
  4944. +   iounmap(urdm->vaddr_uartdm);
  4945. +   urdm->vaddr_uartdm = NULL;
  4946. +   if (urdm->iores_uartdm)
  4947. +       release_mem_region((u32) urdm->pfdata->paddr_uartdm,
  4948. +                           UARTDM_SIZE);
  4949. +
  4950. +   /* Release UARTDM IRQ */
  4951. +   free_irq(urdm->pfdata->irq_uartdm, urdm->pfdata->clk_dev);
  4952. +
  4953. +   return 0;
  4954. +}
  4955. +
  4956. +/**
  4957. + * @brief   Initialize MSM UARTDM port
  4958. + * @details This function executes;\n
  4959. + *            # Alloc and Initialize UARTDM sub-module data\n
  4960. + *            # Get UARTDM clock device\n
  4961. + *            # Create workqueue of UARTDM\n
  4962. + *            # Set UARTDM call back functions\n
  4963. + *            # Call RX buffer init\n
  4964. + *            # Call TX buffer init\n
  4965. + *            # Alloc dummy DMA distination\n
  4966. + *            # Alloc DMA command boxes (RX & TX)
  4967. + * @param   N/A
  4968. + * @retval  0        : Success
  4969. + * @retval  Negative : Failure\n
  4970. + *            -EINVAL = No platform data\n
  4971. + *            -ENOMEM = No enough memory / Cannot create workqueue /
  4972. + *                      RX/TX buffer initialization error
  4973. + *            -ENODEV = Clock device not found
  4974. + * @note
  4975. + */
  4976. +int msm_uartdm_init(struct msm_uartdm_pfdata *pfdata)
  4977. +{
  4978. +   int ret;
  4979. +
  4980. +   pr_debug(PRT_NAME ": %s\n", __func__);
  4981. +
  4982. +   /* Alloc and Initialize UARTDM sub-module data */
  4983. +   if (!pfdata) {
  4984. +       pr_err(PRT_NAME ": Error. No platform data for MSM UARTDM.\n");
  4985. +       return -EINVAL;
  4986. +   }
  4987. +   urdm = kzalloc(sizeof(struct msm_uartdm_data), GFP_KERNEL);
  4988. +   if (!urdm) {
  4989. +       pr_err(PRT_NAME ": Error. No enough mem for PON.\n");
  4990. +       ret = -ENOMEM;
  4991. +       goto err_alloc_uartdm_data;
  4992. +   }
  4993. +   urdm->pfdata = pfdata;
  4994. +
  4995. +   /* Get UARTDM clock device */
  4996. +   urdm->clk_uartdm = clk_get(urdm->pfdata->clk_dev,
  4997. +                   urdm->pfdata->clk_str);
  4998. +   if (IS_ERR(urdm->clk_uartdm)) {
  4999. +       pr_err(PRT_NAME ": Error. UARTDM clock failed.\n");
  5000. +       ret = -ENODEV;
  5001. +       goto err_get_uartdm_clock;
  5002. +   }
  5003. +
  5004. +   spin_lock_init(&urdm->lock);
  5005. +
  5006. +   /* Create workqueue of UARTDM */
  5007. +   urdm->uartdm_wq = create_workqueue(urdm->pfdata->workqueue_name);
  5008. +   if (!urdm->uartdm_wq) {
  5009. +       pr_err(PRT_NAME ": Error. Workqueue failed.\n");
  5010. +       ret = -ENOMEM;
  5011. +       goto err_create_workqueue;
  5012. +   }
  5013. +
  5014. +   /* Set UARTDM call back functions */
  5015. +   INIT_WORK(&urdm->rcv_1byte_work, msm_uartdm_rcv_1byte_work);
  5016. +   INIT_WORK(&urdm->rx_end_work, msm_uartdm_rx_end_work);
  5017. +   INIT_WORK(&urdm->rx_error_work, msm_uartdm_rx_error_work);
  5018. +   INIT_WORK(&urdm->tx_end_work, msm_uartdm_tx_end_work);
  5019. +   INIT_WORK(&urdm->tx_error_work, msm_uartdm_tx_error_work);
  5020. +
  5021. +   /* Call RX buffer init */
  5022. +   ret = felica_rxbuf_init();
  5023. +   if (ret) {
  5024. +       pr_err(PRT_NAME ": Error. RX buffer init failed.\n");
  5025. +       ret = -ENOMEM;
  5026. +       goto err_rx_buf_init;
  5027. +   }
  5028. +
  5029. +   /* Call TX buffer init */
  5030. +   ret = felica_txbuf_init();
  5031. +   if (ret) {
  5032. +       pr_err(PRT_NAME ": Error. TX buffer init failed.\n");
  5033. +       ret = -ENOMEM;
  5034. +       goto err_tx_buf_init;
  5035. +   }
  5036. +
  5037. +   /* Alloc dummy DMA distination */
  5038. +   urdm->dummy_dst_buf = dma_alloc_coherent(NULL,
  5039. +               sizeof(char) * UARTDM_BURST_SIZE,
  5040. +               &urdm->dummy_dst_dmabase, GFP_KERNEL);
  5041. +   if (!urdm->dummy_dst_buf) {
  5042. +       pr_err(PRT_NAME ": Error. Alloc dummy distination.\n");
  5043. +       ret = -ENOMEM;
  5044. +       goto err_alloc_dummy_dst;
  5045. +   }
  5046. +
  5047. +   /* Alloc TX DMOV box */
  5048. +   urdm->txbox = dma_alloc_coherent(NULL, sizeof(dmov_box),
  5049. +                   &urdm->mapped_txbox, GFP_KERNEL);
  5050. +   if (!urdm->txbox) {
  5051. +       pr_err(PRT_NAME ": Error. No enough mem for TXDM.\n");
  5052. +       ret = -ENOMEM;
  5053. +       goto err_alloc_txbox;
  5054. +   }
  5055. +   urdm->txbox_ptr = dma_alloc_coherent(NULL, sizeof(u32 *),
  5056. +               &urdm->mapped_txbox_ptr, GFP_KERNEL);
  5057. +   if (!urdm->txbox_ptr) {
  5058. +       pr_err(PRT_NAME ": Error. No enough mem for TXDM.\n");
  5059. +       ret = -ENOMEM;
  5060. +       goto err_alloc_txbox_ptr;
  5061. +   }
  5062. +
  5063. +   /* Alloc RX DMOV box */
  5064. +   urdm->rxbox = dma_alloc_coherent(NULL, sizeof(dmov_box),
  5065. +                   &urdm->mapped_rxbox, GFP_KERNEL);
  5066. +   if (!urdm->rxbox) {
  5067. +       pr_err(PRT_NAME ": Error. No enough mem for RXDM.\n");
  5068. +       ret = -ENOMEM;
  5069. +       goto err_alloc_rxbox;
  5070. +   }
  5071. +   urdm->rxbox_ptr = dma_alloc_coherent(NULL, sizeof(u32 *),
  5072. +               &urdm->mapped_rxbox_ptr, GFP_KERNEL);
  5073. +   if (!urdm->rxbox_ptr) {
  5074. +       pr_err(PRT_NAME ": Error. No enough mem for RXDM.\n");
  5075. +       ret = -ENOMEM;
  5076. +       goto err_alloc_rxbox_ptr;
  5077. +   }
  5078. +
  5079. +   return 0;
  5080. +
  5081. +err_alloc_rxbox_ptr:
  5082. +   dma_free_coherent(NULL, sizeof(dmov_box), urdm->rxbox,
  5083. +                       urdm->mapped_rxbox);
  5084. +err_alloc_rxbox:
  5085. +   dma_free_coherent(NULL, sizeof(u32 *), urdm->txbox_ptr,
  5086. +                       urdm->mapped_txbox_ptr);
  5087. +err_alloc_txbox_ptr:
  5088. +   dma_free_coherent(NULL, sizeof(dmov_box), urdm->txbox,
  5089. +                       urdm->mapped_txbox);
  5090. +err_alloc_txbox:
  5091. +   dma_free_coherent(NULL, sizeof(char) * UARTDM_BURST_SIZE,
  5092. +           urdm->dummy_dst_buf, urdm->dummy_dst_dmabase);
  5093. +err_alloc_dummy_dst:
  5094. +   felica_txbuf_exit();
  5095. +err_tx_buf_init:
  5096. +   felica_rxbuf_exit();
  5097. +err_rx_buf_init:
  5098. +   destroy_workqueue(urdm->uartdm_wq);
  5099. +err_create_workqueue:
  5100. +err_get_uartdm_clock:
  5101. +   kfree(urdm);
  5102. +   urdm = NULL;
  5103. +err_alloc_uartdm_data:
  5104. +   return ret;
  5105. +}
  5106. +
  5107. +/**
  5108. + * @brief   Unload MSM UARTDM data and release RX&TX buffers
  5109. + * @details This function executes;\n
  5110. + *            # Release DMA command boxes (RX & TX)\n
  5111. + *            # Release dummy DMA distination\n
  5112. + *            # Release TX buffer\n
  5113. + *            # Release RX buffer\n
  5114. + *            # Destroy workqueue of UARTDM\n
  5115. + *            # Release UARTDM sub-module data
  5116. + * @param   N/A
  5117. + * @retval  N/A
  5118. + * @note
  5119. + */
  5120. +void msm_uartdm_exit(void)
  5121. +{
  5122. +   pr_debug(PRT_NAME ": %s\n", __func__);
  5123. +
  5124. +   dma_free_coherent(NULL, sizeof(u32 *), urdm->rxbox_ptr,
  5125. +                       urdm->mapped_rxbox_ptr);
  5126. +   dma_free_coherent(NULL, sizeof(dmov_box), urdm->rxbox,
  5127. +                       urdm->mapped_rxbox);
  5128. +   dma_free_coherent(NULL, sizeof(u32 *), urdm->txbox_ptr,
  5129. +                       urdm->mapped_txbox_ptr);
  5130. +   dma_free_coherent(NULL, sizeof(dmov_box), urdm->txbox,
  5131. +                       urdm->mapped_txbox);
  5132. +   dma_free_coherent(NULL, sizeof(char) * UARTDM_BURST_SIZE,
  5133. +           urdm->dummy_dst_buf, urdm->dummy_dst_dmabase);
  5134. +   felica_txbuf_exit();
  5135. +   felica_rxbuf_exit();
  5136. +   destroy_workqueue(urdm->uartdm_wq);
  5137. +   kfree(urdm);
  5138. +   urdm = NULL;
  5139. +}
  5140. diff -ruN a/4.1.B.0.431//vendor/semc/hardware/felica/msm_uartdm.h b/4.1.B.0.479//vendor/semc/hardware/felica/msm_uartdm.h
  5141. --- a/4.1.B.0.431//vendor/semc/hardware/felica/msm_uartdm.h 1970-01-01 09:00:00.000000000 +0900
  5142. +++ b/4.1.B.0.479//vendor/semc/hardware/felica/msm_uartdm.h 2012-06-25 19:30:44.000000000 +0900
  5143. @@ -0,0 +1,189 @@
  5144. +/* vendor/semc/hardware/felica/msm_uartdm.h
  5145. + *
  5146. + * Copyright (C) 2010 Sony Ericsson Mobile Communications AB.
  5147. + *
  5148. + * Author: Hiroaki Kuriyama <[email protected]>
  5149. + *
  5150. + * This program is free software; you can redistribute it and/or modify
  5151. + * it under the terms of the GNU General Public License version 2, as
  5152. + * published by the Free Software Foundation; either version 2
  5153. + * of the License, or (at your option) any later version.
  5154. + */
  5155. +
  5156. +#ifndef _MSM_UARTDM_H
  5157. +#define _MSM_UARTDM_H
  5158. +
  5159. +struct msm_uartdm_pfdata;
  5160. +
  5161. +int msm_uartdm_init(struct msm_uartdm_pfdata *pfdata);
  5162. +void msm_uartdm_exit(void);
  5163. +int msm_uartdm_open(void);
  5164. +int msm_uartdm_close(void);
  5165. +int msm_uartdm_rx_start(void);
  5166. +int msm_uartdm_rx_reset(void);
  5167. +int msm_uartdm_tx_start(void);
  5168. +int msm_uartdm_tx_reset(void);
  5169. +int msm_uartdm_rcv_1byte_enable(void);
  5170. +int msm_uartdm_rcv_1byte_disable(void);
  5171. +int msm_uartdm_rcv_byte_check(void);
  5172. +
  5173. +/**************************************/
  5174. +/*    MSM7x30 UART DM - Constant -    */
  5175. +/**************************************/
  5176. +#define    UARTDM_SIZE     0x1000
  5177. +#define UARTDM_BURST_SIZE  16
  5178. +
  5179. +/********************************************/
  5180. +/*    MSM7x30 UART DM - Local constant -    */
  5181. +/********************************************/
  5182. +#define LOCAL_UARTDM_BASE_FREQ     (460800 * 16)
  5183. +#define LOCAL_UARTDM_BAUDRATE_CSR  0xFF        /* 460kbps */
  5184. +#define LOCAL_UARTDM_DATA_STOP_PARITY  0x34        /* 8N1 */
  5185. +#define LOCAL_UARTDM_STALE_TIMEOUT 32      /* [char times] */
  5186. +#define LOCAL_UARTDM_TX_RX_FIFO_SPLIT  0x003C  /* Tx240Byte vs Rx272Byte */
  5187. +#define LOCAL_UARTDM_TX_FIFO_SIZE  (4 * LOCAL_UARTDM_TX_RX_FIFO_SPLIT)
  5188. +#define LOCAL_UARTDM_RX_FIFO_SIZE  (512 - LOCAL_UARTDM_TX_FIFO_SIZE)
  5189. +
  5190. +/*********************************************/
  5191. +/*    MSM7x30 UART DM - Register offset -    */
  5192. +/*********************************************/
  5193. +#define    UART_DM_MR1     0x0000
  5194. +#define    UART_DM_MR2     0x0004
  5195. +#define    UART_DM_CSR     0x0008
  5196. +#define    UART_DM_SR      0x0008
  5197. +#define    UART_DM_CR      0x0010
  5198. +#define    UART_DM_MISR        0x0010
  5199. +#define    UART_DM_IMR     0x0014
  5200. +#define    UART_DM_ISR     0x0014
  5201. +#define    UART_DM_IPR     0x0018
  5202. +#define    UART_DM_TFWR        0x001C
  5203. +#define    UART_DM_RFWR        0x0020
  5204. +#define    UART_DM_HCR     0x0024
  5205. +#define    UART_DM_DMRX        0x0034
  5206. +#define    UART_DM_IRDA        0x0038
  5207. +#define    UART_DM_RX_TOTAL_SNAP   0x0038
  5208. +#define    UART_DM_DMEN        0x003C
  5209. +#define    UART_DM_NO_CHARS_FOR_TX 0x0040
  5210. +#define    UART_DM_BADR        0x0044
  5211. +#define    UART_DM_TESTSL      0x0048
  5212. +#define    UART_DM_TXFS        0x004c
  5213. +#define    UART_DM_RXFS        0x0050
  5214. +#define    UART_DM_MISR_MODE   0x0060
  5215. +#define    UART_DM_MISR_RESET  0x0064
  5216. +#define    UART_DM_MISR_EXPORT 0x0068
  5217. +#define    UART_DM_MISR_VAL    0x006c
  5218. +#define    UART_DM_TF      0x0070
  5219. +#define    UART_DM_TF_2        0x0074
  5220. +#define    UART_DM_TF_3        0x0078
  5221. +#define    UART_DM_TF_4        0x007c
  5222. +#define    UART_DM_RF      0x0070
  5223. +#define    UART_DM_RF_2        0x0074
  5224. +#define    UART_DM_RF_3        0x0078
  5225. +#define    UART_DM_RF_4        0x007C
  5226. +#define    UART_DM_SIM_CFG     0x0080
  5227. +#define    UART_DM_TEST_WR_ADDR    0x0084
  5228. +#define    UART_DM_TEST_WR_DATA    0x0088
  5229. +#define    UART_DM_TEST_RD_ADDR    0x008C
  5230. +#define    UART_DM_TEST_RD_DATA    0x0090
  5231. +
  5232. +/*****************************************************/
  5233. +/*    MSM7x30 UART DM - Register bit definition -    */
  5234. +/*****************************************************/
  5235. +#define BIT_32BIT_ALL      0xFFFFFFFF
  5236. +/*** UART_DM_MR2 (R/W) ***/
  5237. +#define BIT_RX_ERROR_CHAR_OFF      0x0200
  5238. +#define BIT_RX_BREAK_ZERO_CHAR_OFF 0x0100
  5239. +#define BIT_ERROR_MODE         0x0040
  5240. +#define BIT_BITS_PER_CHAR      0x0030
  5241. +#define BIT_STOP_BIT_LEN       0x000C
  5242. +#define BIT_PARITY_MODE            0x0003
  5243. +/*** UART_DM_CSR (W) ***/
  5244. +#define BIT_UART_RX_CLK_SEL    0x00F0
  5245. +#define BIT_UART_TX_CLK_SEL    0x000F
  5246. +/*** UART_DM_SR (R) ***/
  5247. +#define BIT_RX_BREAK_START_LAST    0x0100
  5248. +#define BIT_HUNT_CHAR      0x0080
  5249. +#define BIT_RX_BREAK       0x0040
  5250. +#define BIT_PAR_FRAME_ERR  0x0020
  5251. +#define BIT_UART_OVERRUN   0x0010
  5252. +#define BIT_TXEMT      0x0008
  5253. +#define BIT_TXRDY      0x0004
  5254. +#define BIT_RXFULL     0x0002
  5255. +#define BIT_RXRDY      0x0001
  5256. +/*** UART_DM_CR (W) ***/
  5257. +#define BIT_CHANNEL_COMMAND_MSB    0x0800
  5258. +#define BIT_GENERAL_COMMAND    0x0700
  5259. +#define BIT_CHANNEL_COMMAND_LSB    0x00F0
  5260. +#define BIT_UART_TX_DISABLE    0x0008
  5261. +#define BIT_UART_TX_EN     0x0004
  5262. +#define BIT_UART_RX_DISABLE    0x0002
  5263. +#define BIT_UART_RX_EN     0x0001
  5264. +/*** UART_DM_MISR (R) ***/
  5265. +#define BIT_UART_MISR
  5266. +/*** UART_DM_IMR (W) & UART_DM_ISR (R) ***/
  5267. +#define BIT_PAR_FRAME_ERR_IRQ  0x1000
  5268. +#define BIT_RXBREAK_END        0x0800
  5269. +#define BIT_RXBREAK_START  0x0400
  5270. +#define BIT_TX_DONE        0x0200
  5271. +#define BIT_TX_ERROR       0x0100
  5272. +#define BIT_TX_READY       0x0080
  5273. +#define BIT_CURRENT_CTS        0x0040
  5274. +#define BIT_DELTA_CTS      0x0020
  5275. +#define BIT_RXLEV      0x0010
  5276. +#define BIT_RXSTALE        0x0008
  5277. +#define BIT_RXBREAK_CHANGE 0x0004
  5278. +#define BIT_RXHUNT     0x0002
  5279. +#define BIT_TXLEV      0x0001
  5280. +/*** UART_DM_IPR (R/W) ***/
  5281. +#define BIT_STALE_TIMEOUT_MSB  0xFFFFFF80
  5282. +#define BIT_SAMPLE_DATA        0x0040
  5283. +#define BIT_STALE_TIMEOUT_LSB  0x001F
  5284. +/*** UART_DM_TFWR  (R/W) ***/
  5285. +#define BIT_TFW            0xFFFFFFFF
  5286. +/*** UART_DM_RFWR  (R/W) ***/
  5287. +#define BIT_RFW            0xFFFFFFFF
  5288. +/*** UART_DM_DMRX (W/R) ***/
  5289. +#define BIT_RX_DM_CRCI_CHARS   0x01FFFFFF
  5290. +/*** UART_DM_RX_TOTAL_SNAP (R) ***/
  5291. +#define BIT_RX_TOTAL_BYTES 0x00FFFFFF
  5292. +/*** UART_DM_DMEN (R/W) ***/
  5293. +#define BIT_RX_DM_EN       0x0002
  5294. +#define BIT_TX_DM_EN       0x0001
  5295. +/*** UART_DM_NO_CHARS_FOR_TX (R/W) ***/
  5296. +#define BIT_TX_TOTAL_TRANS_LEN 0x00FFFFFF
  5297. +/*** UART_DM_BADR (R/W) ***/
  5298. +#define BIT_RX_BASE_ADDR   0xFFFFFFFC
  5299. +
  5300. +/*********************************************************/
  5301. +/*    MSM7x30 UART DM - Command register definition -    */
  5302. +/*********************************************************/
  5303. +/*** Channel Command  (Bit11)---(Bit7)(Bit6)(Bit5)(Bit4) ***/
  5304. +#define CCMD_NULL_COMMAND          0x00
  5305. +#define CCMD_RESET_RECEIVER            0x10
  5306. +#define CCMD_RESET_TRANSMITTER         0x20
  5307. +#define CCMD_RESET_ERROR_STATUS            0x30
  5308. +#define CCMD_BREAK_CHANGE_INTERRUPT        0x40
  5309. +#define CCMD_START_BREAK           0x50
  5310. +#define CCMD_STOP_BREAK                0x60
  5311. +#define CCMD_RESET_CTS_N           0x70
  5312. +#define CCMD_RESET_STALE_INTERRUPT     0x80
  5313. +#define CCMD_PACKET_MODE           0x90
  5314. +#define CCMD_MODE_RESET                0xC0
  5315. +#define CCMD_SET_RFR_N             0xD0
  5316. +#define CCMD_RESET_RFR_N           0xE0
  5317. +#define CCMD_RESET_TX_ERROR            0x800
  5318. +#define CCMD_CLEAR_TX_DONE         0x810
  5319. +#define CCMD_RESET_BREAK_START_INTERRUPT   0x820
  5320. +#define CCMD_BREAK_END_INTERRUPT       0x830
  5321. +#define CCMD_RESET_PER_FRAME_ERR_INTERRUPT 0x840
  5322. +
  5323. +/*** General Command  (Bit10)(Bit9)(Bit8) ***/
  5324. +#define GCMD_NULL_COMMAND          0x000
  5325. +#define GCMD_CR_PROTECTION_ENABLE      0x100
  5326. +#define GCMD_CR_PROTECTION_DISABLE     0x200
  5327. +#define GCMD_RESET_TX_READY_INTERRUPT      0x300
  5328. +#define GCMD_ENABLE_STALE_EVENT            0x500
  5329. +#define GCMD_DISABLE_STALE_EVENT       0x600
  5330. +#define GCMD_SW_FORCE_STALE            0x400
  5331. +
  5332. +#endif
  5333. diff -ruN a/4.1.B.0.431//vendor/semc/hardware/felica/msm_uartmux.c b/4.1.B.0.479//vendor/semc/hardware/felica/msm_uartmux.c
  5334. --- a/4.1.B.0.431//vendor/semc/hardware/felica/msm_uartmux.c    1970-01-01 09:00:00.000000000 +0900
  5335. +++ b/4.1.B.0.479//vendor/semc/hardware/felica/msm_uartmux.c    2012-06-25 19:30:44.000000000 +0900
  5336. @@ -0,0 +1,128 @@
  5337. +/* vendor/semc/hardware/felica/msm_uartmux.c
  5338. + *
  5339. + * Copyright (C) 2010 Sony Ericsson Mobile Communications AB.
  5340. + *
  5341. + * Author: Hiroaki Kuriyama <[email protected]>
  5342. + *
  5343. + * This program is free software; you can redistribute it and/or modify
  5344. + * it under the terms of the GNU General Public License version 2, as
  5345. + * published by the Free Software Foundation; either version 2
  5346. + * of the License, or (at your option) any later version.
  5347. + */
  5348. +
  5349. +#include <linux/kernel.h>
  5350. +#include <linux/stddef.h>
  5351. +#include <linux/mfd/pmic8058.h>
  5352. +#include <linux/pmic8058-nfc.h>
  5353. +#include "msm_uartmux.h"
  5354. +
  5355. +#define PRT_NAME "msm uartmux"
  5356. +
  5357. +/**
  5358. + * @brief  Get pmic device information
  5359. + * @param  N/A
  5360. + * @retval Valid address : Pointer to PMIC device
  5361. + * @retval NULL : Cannot find PM8058 device
  5362. + */
  5363. +static struct pm8058_chip *msm_uartmux_pmic_info(void)
  5364. +{
  5365. +   struct pm8058_nfc_device *nfcdev;
  5366. +
  5367. +   pr_debug(PRT_NAME ": %s\n", __func__);
  5368. +
  5369. +   nfcdev = pm8058_nfc_request();
  5370. +   if (!nfcdev)
  5371. +       return NULL;
  5372. +   if (!nfcdev->pm_chip)
  5373. +       return NULL;
  5374. +
  5375. +   return nfcdev->pm_chip;
  5376. +}
  5377. +
  5378. +/**
  5379. + * @brief  Get uartmux state
  5380. + * @param  N/A
  5381. + * @retval 0/Positive : Success, value of UART MUX.
  5382. + * @retval Negative : Failure\n
  5383. + *           -ENODEV = Cannot find PM8058 device\n
  5384. + *           -EIO    = Cannot read value from PM8058
  5385. + */
  5386. +int msm_uartmux_get(void)
  5387. +{
  5388. +   static struct pm8058_chip *pmdev;
  5389. +   int ret;
  5390. +   char misc = 0x00;
  5391. +
  5392. +   pr_debug(PRT_NAME ": %s\n", __func__);
  5393. +
  5394. +   pmdev = msm_uartmux_pmic_info();
  5395. +   if (!pmdev) {
  5396. +       pr_err(PRT_NAME ": Error. Dev not found.\n");
  5397. +       return -ENODEV;
  5398. +   }
  5399. +
  5400. +   ret = pm8058_read(pmdev, SSBI_REG_ADDR_MISC, &misc, 1);
  5401. +   if (ret) {
  5402. +       pr_err(PRT_NAME ": Error. Cannot read UART MUX.\n");
  5403. +       return -EIO;
  5404. +   }
  5405. +
  5406. +   misc &= PM8058_UART_MUX_MASK;   /* Needed to delete unused bits */
  5407. +   pr_debug(PRT_NAME ": UART MUX = %d.\n", (int) misc);
  5408. +
  5409. +   return (int) misc;
  5410. +}
  5411. +
  5412. +/**
  5413. + * @brief  Set uartmux state
  5414. + * @param  value : Value to write.
  5415. + * @retval 0 : Success
  5416. + * @retval Negative : Failure\n
  5417. + *           -ENODEV = Cannot find PM8058 device\n
  5418. + *           -EIO    = Cannot write value to PM8058
  5419. + */
  5420. +int msm_uartmux_set(int value)
  5421. +{
  5422. +   struct pm8058_chip *pmdev;
  5423. +   int ret;
  5424. +
  5425. +   pr_debug(PRT_NAME ": %s\n", __func__);
  5426. +
  5427. +   pmdev = msm_uartmux_pmic_info();
  5428. +   if (!pmdev) {
  5429. +       pr_err(PRT_NAME ": Error. Dev not found.\n");
  5430. +       return -ENODEV;
  5431. +   }
  5432. +
  5433. +   ret = pm8058_misc_control(pmdev, PM8058_UART_MUX_MASK, value);
  5434. +   if (ret) {
  5435. +       pr_err(PRT_NAME ": Error. Cannot write UART MUX.");
  5436. +       return -EIO;
  5437. +   }
  5438. +
  5439. +   return 0;
  5440. +}
  5441. +
  5442. +/**
  5443. + * @brief   Init funtion for MSM UARTMUX
  5444. + * @param   N/A
  5445. + * @retval  0 : Success
  5446. + * @note    No initialization is needed for UART MUX.
  5447. + */
  5448. +int msm_uartmux_init(void)
  5449. +{
  5450. +   pr_debug(PRT_NAME ": %s\n", __func__);
  5451. +
  5452. +   return 0;
  5453. +}
  5454. +
  5455. +/**
  5456. + * @brief   Exit function for MSM UARTMUX
  5457. + * @param   N/A
  5458. + * @retval  N/A
  5459. + * @note
  5460. + */
  5461. +void msm_uartmux_exit(void)
  5462. +{
  5463. +   pr_debug(PRT_NAME ": %s\n", __func__);
  5464. +}
  5465. diff -ruN a/4.1.B.0.431//vendor/semc/hardware/felica/msm_uartmux.h b/4.1.B.0.479//vendor/semc/hardware/felica/msm_uartmux.h
  5466. --- a/4.1.B.0.431//vendor/semc/hardware/felica/msm_uartmux.h    1970-01-01 09:00:00.000000000 +0900
  5467. +++ b/4.1.B.0.479//vendor/semc/hardware/felica/msm_uartmux.h    2012-06-25 19:30:44.000000000 +0900
  5468. @@ -0,0 +1,31 @@
  5469. +/* vendor/semc/hardware/felica/msm_uartmux.h
  5470. + *
  5471. + * Copyright (C) 2010 Sony Ericsson Mobile Communications AB.
  5472. + *
  5473. + * Author: Hiroaki Kuriyama <[email protected]>
  5474. + *
  5475. + * This program is free software; you can redistribute it and/or modify
  5476. + * it under the terms of the GNU General Public License version 2, as
  5477. + * published by the Free Software Foundation; either version 2
  5478. + * of the License, or (at your option) any later version.
  5479. + */
  5480. +
  5481. +#ifndef _MSM_UARTMUX_H
  5482. +#define _MSM_UARTMUX_H
  5483. +
  5484. +#define    SSBI_REG_ADDR_MISC  0x1CC
  5485. +
  5486. +#include <linux/mutex.h>
  5487. +
  5488. +int msm_uartmux_get(void);
  5489. +int msm_uartmux_set(int);
  5490. +
  5491. +int msm_uartmux_init(void);
  5492. +void msm_uartmux_exit(void);
  5493. +
  5494. +struct pm8058_nfc_device {
  5495. +   struct mutex        nfc_mutex;
  5496. +   struct pm8058_chip  *pm_chip;
  5497. +};
  5498. +
  5499. +#endif
  5500. diff -ruN a/4.1.B.0.431//vendor/semc/hardware/felica/semc_felica_ext.h b/4.1.B.0.479//vendor/semc/hardware/felica/semc_felica_ext.h
  5501. --- a/4.1.B.0.431//vendor/semc/hardware/felica/semc_felica_ext.h    1970-01-01 09:00:00.000000000 +0900
  5502. +++ b/4.1.B.0.479//vendor/semc/hardware/felica/semc_felica_ext.h    2012-06-25 19:30:44.000000000 +0900
  5503. @@ -0,0 +1,69 @@
  5504. +/* vendor/semc/hardware/felica/semc_felica_ext.h
  5505. + *
  5506. + * Copyright (C) 2010 Sony Ericsson Mobile Communications AB.
  5507. + *
  5508. + * Author: Hiroaki Kuriyama <[email protected]>
  5509. + *
  5510. + * This program is free software; you can redistribute it and/or modify
  5511. + * it under the terms of the GNU General Public License version 2, as
  5512. + * published by the Free Software Foundation; either version 2
  5513. + * of the License, or (at your option) any later version.
  5514. + */
  5515. +
  5516. +#ifndef _SEMC_FELICA_EXT_H
  5517. +#define _SEMC_FELICA_EXT_H
  5518. +
  5519. +/* FeliCa Platform Data structures */
  5520. +struct msm_uartdm_pfdata {
  5521. +   char    *paddr_uartdm;
  5522. +   int irq_uartdm;
  5523. +   char    irq_name[16];
  5524. +   int chan_uartdm_tx;
  5525. +   int crci_uartdm_tx;
  5526. +   int chan_uartdm_rx;
  5527. +   int crci_uartdm_rx;
  5528. +   char    clk_str[16];
  5529. +   struct device   *clk_dev;
  5530. +   char    workqueue_name[16];
  5531. +   char    iomem_name[16];
  5532. +   void    (*callback_rcv_1byte)(void);
  5533. +   void    (*callback_rx_complete)(void);
  5534. +   void    (*callback_rx_error)(void);
  5535. +   void    (*callback_tx_complete)(void);
  5536. +   void    (*callback_tx_error)(void);
  5537. +};
  5538. +
  5539. +struct felica_uart_pfdata {
  5540. +   struct msm_uartdm_pfdata    uartdm_pfdata;
  5541. +   int uartmux_neutral;
  5542. +   int uartmux_felica;
  5543. +};
  5544. +
  5545. +struct felica_cen_pfdata {
  5546. +};
  5547. +
  5548. +struct felica_pon_pfdata {
  5549. +   int gpio_pon;
  5550. +   int (*tvdd_on)(void);
  5551. +   void    (*tvdd_off)(void);
  5552. +};
  5553. +
  5554. +struct felica_rfs_pfdata {
  5555. +   int gpio_rfs;
  5556. +};
  5557. +
  5558. +struct felica_int_pfdata {
  5559. +   int gpio_int;
  5560. +   int irq_int;
  5561. +};
  5562. +
  5563. +struct felica_platform_data {
  5564. +   struct felica_uart_pfdata   uart_pfdata;
  5565. +   struct felica_cen_pfdata    cen_pfdata;
  5566. +   struct felica_pon_pfdata    pon_pfdata;
  5567. +   struct felica_rfs_pfdata    rfs_pfdata;
  5568. +   struct felica_int_pfdata    int_pfdata;
  5569. +   int (*gpio_init)(void);
  5570. +};
  5571. +
  5572. +#endif
  5573. diff -ruN a/4.1.B.0.431//vendor/semc/hardware/irda/Android.mk b/4.1.B.0.479//vendor/semc/hardware/irda/Android.mk
  5574. --- a/4.1.B.0.431//vendor/semc/hardware/irda/Android.mk 1970-01-01 09:00:00.000000000 +0900
  5575. +++ b/4.1.B.0.479//vendor/semc/hardware/irda/Android.mk 2012-06-25 19:30:44.000000000 +0900
  5576. @@ -0,0 +1,49 @@
  5577. +ifeq ($(SEMC_CFG_IRDA_DRIVER),true)
  5578. +
  5579. +LOCAL_PATH:= $(call my-dir)
  5580. +SAVED_LOCAL_PATH_IR:= $(LOCAL_PATH)
  5581. +
  5582. +include $(CLEAR_VARS)
  5583. +
  5584. +# now the part that is actually built
  5585. +
  5586. +LOCAL_PATH_ABS_IR := $(shell cd $(SAVED_LOCAL_PATH_IR) && pwd)
  5587. +
  5588. +BUILD_ROOT_IR := $(TARGET_OUT_INTERMEDIATES)/SEMC_MSM_IRDA_OBJ
  5589. +
  5590. +BUILD_SUBDIRS_IR := $(shell cd $(SAVED_LOCAL_PATH_IR) && find . -type d)
  5591. +BUILD_SRC_IR := $(shell cd $(SAVED_LOCAL_PATH_IR) && find . -name \*[ch])
  5592. +BUILD_MK_IR := $(shell cd $(SAVED_LOCAL_PATH_IR) && find . -name Makefile)
  5593. +
  5594. +REL_SUBDIRS_IR := $(addprefix $(SAVED_LOCAL_PATH_IR)/, $(BUILD_SUBDIRS_IR))
  5595. +REL_SRC_IR := $(addprefix $(SAVED_LOCAL_PATH_IR)/, $(BUILD_SRC_IR))
  5596. +REL_MK_IR := $(addprefix $(SAVED_LOCAL_PATH_IR)/, $(BUILD_MK_IR))
  5597. +
  5598. +
  5599. +$(BUILD_ROOT_IR)/semc_msm_irda.ko: $(PRODUCT_OUT)/kernel irprep
  5600. +   @(cd $(BUILD_ROOT_IR); $(MAKE) KERNEL_DIR=$(ANDROID_PRODUCT_OUT)/obj/KERNEL_OBJ -f Makefile)
  5601. +
  5602. +
  5603. +irprep: irsubdirs irsrc irmk
  5604. +
  5605. +irsubdirs: $(REL_SUBDIRS_IR)
  5606. +   @(for i in $(BUILD_SUBDIRS_IR); do mkdir -p $(BUILD_ROOT_IR)/$$i; done)
  5607. +
  5608. +irsrc: $(REL_SRC_IR) irsubdirs
  5609. +   @(for i in $(BUILD_SRC_IR); do test -e $(BUILD_ROOT_IR)/$$i || ln -sf $(LOCAL_PATH_ABS_IR)/$$i $(BUILD_ROOT_IR)/$$i; done)
  5610. +
  5611. +irmk: $(REL_MK_IR) irsubdirs
  5612. +   @(for i in $(BUILD_MK_IR); do test -e $(BUILD_ROOT_IR)/$$i || ln -sf $(LOCAL_PATH_ABS_IR)/$$i $(BUILD_ROOT_IR)/$$i; done)
  5613. +
  5614. +# copy the modules
  5615. +files := semc_msm_irda.ko
  5616. +
  5617. +copy_to := $(addprefix $(TARGET_OUT)/lib/modules/,$(files))
  5618. +copy_from := $(addprefix $(BUILD_ROOT_IR)/,$(files))
  5619. +
  5620. +$(TARGET_OUT)/lib/modules/%.ko : $(BUILD_ROOT_IR)/%.ko | $(ACP)
  5621. +   $(transform-prebuilt-to-target)
  5622. +
  5623. +ALL_PREBUILT += $(copy_to)
  5624. +
  5625. +endif
  5626. diff -ruN a/4.1.B.0.431//vendor/semc/hardware/irda/Makefile b/4.1.B.0.479//vendor/semc/hardware/irda/Makefile
  5627. --- a/4.1.B.0.431//vendor/semc/hardware/irda/Makefile   1970-01-01 09:00:00.000000000 +0900
  5628. +++ b/4.1.B.0.479//vendor/semc/hardware/irda/Makefile   2012-06-25 19:30:44.000000000 +0900
  5629. @@ -0,0 +1,20 @@
  5630. +#
  5631. +# Makefile for semc_msm_irda_module
  5632. +#
  5633. +# Copyright 2011 Sony Ericsson Mobile Communications Japan Inc.
  5634. +# All rights, including trade secret rights, reserved.
  5635. +#
  5636. +
  5637. +# environment variables
  5638. +CROSS_COMPILE  := arm-eabi-
  5639. +ARCH           := arm
  5640. +PWD := $(shell pwd)
  5641. +
  5642. +obj-m = semc_msm_irda.o
  5643. +semc_msm_irda_module-objs = semc_msm_irda.o
  5644. +
  5645. +all:
  5646. +   $(MAKE) CROSS_COMPILE=$(CROSS_COMPILE) ARCH=$(ARCH) -C $(KERNEL_DIR) M=$(PWD) modules
  5647. +
  5648. +clean:
  5649. +   $(MAKE) CROSS_COMPILE=$(CROSS_COMPILE) ARCH=$(ARCH) -C $(KERNEL_DIR) M=$(PWD) clean
  5650. diff -ruN a/4.1.B.0.431//vendor/semc/hardware/irda/semc_msm_irda.c b/4.1.B.0.479//vendor/semc/hardware/irda/semc_msm_irda.c
  5651. --- a/4.1.B.0.431//vendor/semc/hardware/irda/semc_msm_irda.c    1970-01-01 09:00:00.000000000 +0900
  5652. +++ b/4.1.B.0.479//vendor/semc/hardware/irda/semc_msm_irda.c    2012-06-25 19:30:44.000000000 +0900
  5653. @@ -0,0 +1,1241 @@
  5654. +/* drivers/serial/semc_irda/semc_msm_irda.c
  5655. + *
  5656. + * Copyright (C) 2011 Sony Ericsson Mobile Communications AB.
  5657. + *
  5658. + * Author: Manabu Yoshida <[email protected]>
  5659. + *
  5660. + * This program is free software; you can redistribute it and/or modify
  5661. + * it under the terms of the GNU General Public License version 2, as
  5662. + * published by the Free Software Foundation; either version 2
  5663. + * of the License, or (at your option) any later version.
  5664. + */
  5665. +
  5666. +#include <linux/module.h>
  5667. +#include <linux/kernel.h>
  5668. +#include <linux/init.h>
  5669. +#include <linux/types.h>
  5670. +#include <linux/gpio.h>
  5671. +#include <linux/fs.h>
  5672. +#include <linux/miscdevice.h>
  5673. +#include <linux/mfd/pmic8058.h>
  5674. +#include <linux/pmic8058-nfc.h>
  5675. +#include <linux/delay.h>
  5676. +#include <linux/uaccess.h>
  5677. +#include <linux/semaphore.h>
  5678. +#include <linux/clk.h>
  5679. +#include <linux/wait.h>
  5680. +#include <linux/dma-mapping.h>
  5681. +#include <linux/poll.h>
  5682. +
  5683. +#include <linux/serial_core.h>
  5684. +
  5685. +#include "semc_msm_irda.h"
  5686. +
  5687. +#include <mach/dma.h>
  5688. +
  5689. +#define DRV_NAME "semc-msm-irda"
  5690. +#define DRV_VERSION "1.0"
  5691. +
  5692. +/* UART DM Register size */
  5693. +#define    UARTDM_SIZE     0x1000
  5694. +#define UARTDM_BURST_SIZE  16
  5695. +
  5696. +/* UART DM Registers */
  5697. +#define UARTDM_MR2    0x0004
  5698. +#define UARTDM_CSR    0x0008 /* write only */
  5699. +#define UARTDM_SR     0x0008 /* read only  */
  5700. +#define UARTDM_CR     0x0010 /* write only */
  5701. +#define UARTDM_IMR    0x0014 /* write only */
  5702. +#define UARTDM_ISR    0x0014 /* read only  */
  5703. +#define UARTDM_IPR    0x0018
  5704. +#define UARTDM_TFWR   0x001c
  5705. +#define UARTDM_RFWR   0x0020
  5706. +#define UARTDM_DMRX   0x0034
  5707. +#define UARTDM_IRDA   0x0038
  5708. +#define UARTDM_RX_TOTAL_SNAP 0x0038 /* read only */
  5709. +#define UARTDM_DMEN   0x003c
  5710. +#define UARTDM_NCF_TX 0x0040
  5711. +#define UARTDM_BADR   0x0044
  5712. +#define UARTDM_TF     0x0070 /* write only */
  5713. +#define UARTDM_RF     0x0070 /* read only  */
  5714. +
  5715. +/* Bit Definition */
  5716. +/* UARTDM_SR (R) */
  5717. +#define BIT_TXEMT      0x0008
  5718. +/* UARTDM_CR (W) */
  5719. +#define BIT_UART_TX_DISABLE    0x0008
  5720. +#define BIT_UART_TX_EN     0x0004
  5721. +#define BIT_UART_RX_DISABLE    0x0002
  5722. +#define BIT_UART_RX_EN     0x0001
  5723. +/* UARTDM_IMR (W) */
  5724. +#define BIT_TX_READY       0x0080
  5725. +#define BIT_RXLEV      0x0010
  5726. +#define BIT_RXSTALE        0x0008
  5727. +/* UARTDM_IPR (R/W) */
  5728. +#define BIT_STALE_TIMEOUT_MSB  0xFFFFFF80
  5729. +#define BIT_STALE_TIMEOUT_LSB  0x001F
  5730. +/* UARTDM_IRDA (W) */
  5731. +#define BIT_MEDIUM_RATE_EN 0x0010
  5732. +#define BIT_INVERT_IRDA_RX 0x0002
  5733. +#define BIT_IRDA_EN        0x0001
  5734. +/* UARTDM_RX_TOTAL_SNAP (R) */
  5735. +#define BIT_RX_TOTAL_BYTES 0x00FFFFFF
  5736. +/* UARTDM_DMEN (R/W) */
  5737. +#define BIT_RX_DM_EN       0x0002
  5738. +#define BIT_TX_DM_EN       0x0001
  5739. +
  5740. +/* Command Definition */
  5741. +/* Channel Commands (Bit11)---(Bit7)(Bit6)(Bit5)(Bit4) */
  5742. +#define CCMD_NULL_COMMAND      0x00
  5743. +#define CCMD_RESET_RECEIVER        0x10
  5744. +#define CCMD_RESET_TRANSMITTER     0x20
  5745. +#define CCMD_RESET_ERROR_STATUS        0x30
  5746. +#define CCMD_BREAK_CHANGE_INTERRUPT    0x40
  5747. +#define CCMD_START_BREAK       0x50
  5748. +#define CCMD_STOP_BREAK            0x60
  5749. +#define CCMD_RESET_CTS_N       0x70
  5750. +#define CCMD_RESET_STALE_INTERRUPT 0x80
  5751. +#define CCMD_PACKET_MODE       0x90
  5752. +#define CCMD_MODE_RESET            0xC0
  5753. +#define CCMD_SET_RFR_N         0xD0
  5754. +#define CCMD_RESET_RFR_N       0xE0
  5755. +#define CCMD_RESET_TX_ERROR        0x800
  5756. +#define CCMD_CLEAR_TX_DONE     0x810
  5757. +#define CCMD_RESET_BREAK_START_INTERRUPT   0x820
  5758. +#define CCMD_BREAK_END_INTERRUPT   0x830
  5759. +#define CCMD_RESET_PER_FRAME_ERR_INTERRUPT 0x840
  5760. +
  5761. +/* General Commands -(Bit10)(Bit9)(Bit8)---- */
  5762. +#define GCMD_NULL_COMMAND      0x000
  5763. +#define GCMD_CR_PROTECTION_ENABLE  0x100
  5764. +#define GCMD_CR_PROTECTION_DISABLE 0x200
  5765. +#define GCMD_RESET_TX_READY_INTERRUPT  0x300
  5766. +#define GCMD_ENABLE_STALE_EVENT        0x500
  5767. +#define GCMD_DISABLE_STALE_EVENT   0x600
  5768. +#define GCMD_SW_FORCE_STALE        0x400
  5769. +
  5770. +/* PM MISC reg*/
  5771. +#define    SSBI_REG_ADDR_MISC      0x1CC
  5772. +
  5773. +/* IrDA UART2DM settings */
  5774. +#define IRUART_UARTDM_CLK(bps)  (((bps) > 460800) ? (bps * 16) : 7372800)
  5775. +#define IRUART_DEF_BAUDRATE_CSR    0x55        /* 9600 bps */
  5776. +#define IRUART_DEF_RXSTALE 32      /* character times */
  5777. +#define IRUART_DATA_STOP_PARITY    0x34        /* 8N1 */
  5778. +
  5779. +#define IRUART_FSYNC_TIMEOUT (3*HZ)
  5780. +
  5781. +/* IrDA UART settings */
  5782. +#define IRUART_IRDA_EN          (BIT_INVERT_IRDA_RX | BIT_IRDA_EN)
  5783. +#define IRUART_IRDA_DISABLE     0x0
  5784. +
  5785. +enum irda_state {
  5786. +   IRDA_UART_CLOSE,
  5787. +   IRDA_UART_OPEN,
  5788. +};
  5789. +enum irda_overflow {
  5790. +   IRDA_NORMAL,
  5791. +   IRDA_OVERFLOW,
  5792. +};
  5793. +enum irda_rx_state {
  5794. +   IRDA_RX_IDLE,
  5795. +   IRDA_RX_START,
  5796. +   IRDA_RX_CB,
  5797. +};
  5798. +
  5799. +struct pm8058_nfc_device {
  5800. +   struct mutex        nfc_mutex;
  5801. +   struct pm8058_chip  *pm_chip;
  5802. +};
  5803. +
  5804. +struct irda_driver_data {
  5805. +   struct irda_platform_data   *pfdata;
  5806. +
  5807. +   struct pm8058_nfc_device    *nfcdev;
  5808. +
  5809. +   enum irda_state         state;
  5810. +   enum irda_overflow      rx_overflow;
  5811. +   enum irda_rx_state      rx_state;
  5812. +   int             bps;
  5813. +
  5814. +   int             refcount;
  5815. +   struct semaphore        sem;
  5816. +   spinlock_t          lock;
  5817. +
  5818. +   u32             imr_reg;
  5819. +   wait_queue_head_t       wait_tx;
  5820. +   wait_queue_head_t       wait_rx;
  5821. +   int             condition_tx;
  5822. +   int             condition_rx;
  5823. +
  5824. +   struct tasklet_struct       tasklet_rxfer_s;
  5825. +   struct tasklet_struct       tasklet_rxfer_e;
  5826. +   struct tasklet_struct       tasklet_txfer;
  5827. +
  5828. +   u8              *vaddr_uartdm;
  5829. +   struct resource         *iores_uartdm;
  5830. +   struct clk          *clk_uartdm;
  5831. +
  5832. +   struct irtxbuf_all      txbuf;
  5833. +   struct irrxbuf_all      rxbuf;
  5834. +
  5835. +   struct msm_dmov_cmd     txdmov_cmd;
  5836. +   dmov_box            *txbox;
  5837. +   u32             *txbox_ptr;
  5838. +   dma_addr_t          mapped_txbox;
  5839. +   dma_addr_t          mapped_txbox_ptr;
  5840. +
  5841. +   struct msm_dmov_cmd     rxdmov_cmd;
  5842. +   dmov_box            *rxbox;
  5843. +   u32             *rxbox_ptr;
  5844. +   dma_addr_t          mapped_rxbox;
  5845. +   dma_addr_t          mapped_rxbox_ptr;
  5846. +};
  5847. +
  5848. +/* Local datas */
  5849. +static struct irda_driver_data *irc;
  5850. +
  5851. +/* Local functions */
  5852. +static u32  msm_uartdm_read(u32 offset);
  5853. +static void msm_uartdm_write(u32 offset, u32 value);
  5854. +static void irda_txbuf_clear(struct irtxbuf_all *);
  5855. +static void irda_rxbuf_clear(struct irrxbuf_all *);
  5856. +static void irda_txdmov_callback(
  5857. +struct msm_dmov_cmd *, unsigned int, struct msm_dmov_errdata *);
  5858. +static void irda_rxdmov_callback(
  5859. +struct msm_dmov_cmd *, unsigned int, struct msm_dmov_errdata *);
  5860. +static void irda_uart_txfer_exec(unsigned long);
  5861. +static void irda_uart_rxfer_start(unsigned long);
  5862. +static void irda_uart_rxfer_end(unsigned long);
  5863. +static irqreturn_t irda_uart_irq_handler(int, void *);
  5864. +static unsigned int irda_baudrate_set(unsigned int bps);
  5865. +
  5866. +
  5867. +static unsigned int msm_uartdm_read(u32 offset)
  5868. +{
  5869. +   if (offset >= UARTDM_SIZE) {
  5870. +       printk(KERN_ERR DRV_NAME ": msm_uartdm_read invalid offset\n");
  5871. +       return 0x0;
  5872. +   }
  5873. +   return ioread32(irc->vaddr_uartdm + offset);
  5874. +}
  5875. +
  5876. +static void msm_uartdm_write(u32 offset, u32 value)
  5877. +{
  5878. +   if (offset >= UARTDM_SIZE) {
  5879. +       printk(KERN_ERR DRV_NAME ": msm_uartdm_write invalid offset\n");
  5880. +       return;
  5881. +   }
  5882. +   iowrite32(value, irc->vaddr_uartdm + offset);
  5883. +}
  5884. +
  5885. +static void irda_txbuf_clear(struct irtxbuf_all *p_txbuf)
  5886. +{
  5887. +   p_txbuf->ptr = 0;
  5888. +   p_txbuf->num = 0;
  5889. +}
  5890. +
  5891. +static void irda_rxbuf_clear(struct irrxbuf_all *p_rxbuf)
  5892. +{
  5893. +   p_rxbuf->wp = 0;
  5894. +   p_rxbuf->rp = 0;
  5895. +}
  5896. +
  5897. +static void irda_txdmov_callback(
  5898. +   struct msm_dmov_cmd *cmd_ptr,
  5899. +   unsigned int result,
  5900. +   struct msm_dmov_errdata *err)
  5901. +{
  5902. +   unsigned long flags;
  5903. +
  5904. +   WARN_ON(result != 0x80000002);  /* DMA did not finish properly */
  5905. +
  5906. +   spin_lock_irqsave(&irc->lock, flags);
  5907. +   irc->imr_reg |= BIT_TX_READY;
  5908. +   msm_uartdm_write(UARTDM_IMR, irc->imr_reg);
  5909. +   spin_unlock_irqrestore(&irc->lock, flags);
  5910. +}
  5911. +
  5912. +static void irda_rxdmov_callback(
  5913. +   struct msm_dmov_cmd *cmd_ptr, unsigned int result,
  5914. +   struct msm_dmov_errdata *err)
  5915. +{
  5916. +   if (irc->rx_state == IRDA_RX_START) {
  5917. +       irc->rx_state = IRDA_RX_CB;
  5918. +       tasklet_schedule(&irc->tasklet_rxfer_e);
  5919. +   } else {
  5920. +       printk(KERN_INFO DRV_NAME ": rxdmov callback is invalid.\n");
  5921. +   }
  5922. +}
  5923. +
  5924. +static void irda_uart_rxfer_start(unsigned long data)
  5925. +{
  5926. +   unsigned long flags;
  5927. +
  5928. +   spin_lock_irqsave(&irc->lock, flags);
  5929. +
  5930. +   if (irc->rx_state != IRDA_RX_IDLE) {
  5931. +       printk(KERN_INFO DRV_NAME ": rx state is not idle (%d).\n",
  5932. +           irc->rx_state);
  5933. +       goto out;
  5934. +   }
  5935. +   irc->rx_state = IRDA_RX_START;
  5936. +
  5937. +   /* Update DMOV destination */
  5938. +   irc->rxbox->dst_row_addr = irc->rxbuf.dmabase;
  5939. +
  5940. +   /* Enqueue RX DMOV request */
  5941. +   msm_dmov_enqueue_cmd(irc->pfdata->chan_uartdm_rx, &irc->rxdmov_cmd);
  5942. +
  5943. +   /* Write DMRX register*/
  5944. +   msm_uartdm_write(UARTDM_DMRX, IRUART_SW_RXBUF_SIZE);
  5945. +
  5946. +   /* Enable RX stale*/
  5947. +   irc->imr_reg |= BIT_RXSTALE;
  5948. +   msm_uartdm_write(UARTDM_IMR, irc->imr_reg);
  5949. +   msm_uartdm_write(UARTDM_CR, GCMD_ENABLE_STALE_EVENT);
  5950. +
  5951. +out:
  5952. +   spin_unlock_irqrestore(&irc->lock, flags);
  5953. +}
  5954. +
  5955. +static void irda_uart_rxfer_end(unsigned long data)
  5956. +{
  5957. +   int num, wp, rp, wlen1, wlen2, remd;
  5958. +   unsigned long flags;
  5959. +
  5960. +   spin_lock_irqsave(&irc->lock, flags);
  5961. +
  5962. +   irc->rx_state = IRDA_RX_IDLE;
  5963. +
  5964. +   /* Disable and Reset RXSTALE */
  5965. +   irc->imr_reg &= ~BIT_RXSTALE;
  5966. +   msm_uartdm_write(UARTDM_IMR, irc->imr_reg);
  5967. +   msm_uartdm_write(UARTDM_CR, GCMD_DISABLE_STALE_EVENT);
  5968. +   msm_uartdm_write(UARTDM_CR, CCMD_RESET_STALE_INTERRUPT);
  5969. +
  5970. +   if (irc->rx_overflow == IRDA_OVERFLOW) {
  5971. +       printk(KERN_ERR DRV_NAME ": RX SW buf overflowed.\n");
  5972. +       num = 0;
  5973. +       goto out;
  5974. +   }
  5975. +
  5976. +   /* Update SW RX ring buffer */
  5977. +   num = msm_uartdm_read(UARTDM_RX_TOTAL_SNAP) & BIT_RX_TOTAL_BYTES;
  5978. +   wlen1 = 0;
  5979. +   wlen2 = 0;
  5980. +   wp = irc->rxbuf.wp;
  5981. +   rp = irc->rxbuf.rp;
  5982. +
  5983. +   /* Get remainder of ring buffer */
  5984. +   remd = 0;
  5985. +   if (wp < rp)
  5986. +       remd = irc->rxbuf.rp - irc->rxbuf.wp;
  5987. +   else
  5988. +       remd = (IRUART_SW_RXRINGBUF_SIZE - irc->rxbuf.wp)
  5989. +           + irc->rxbuf.rp;
  5990. +   if (remd <= num) {
  5991. +       irc->rx_overflow = IRDA_OVERFLOW;
  5992. +       printk(KERN_ERR DRV_NAME ": RX SW buf overflowed.\n");
  5993. +       printk(KERN_ERR DRV_NAME ": num(%d), remd(%d).\n", num, remd);
  5994. +       num = remd;
  5995. +   }
  5996. +
  5997. +   if ((wp + num) > IRUART_SW_RXRINGBUF_SIZE) {
  5998. +       wlen1 = IRUART_SW_RXRINGBUF_SIZE - wp;
  5999. +       wlen2 = num - wlen1;
  6000. +   } else {
  6001. +       wlen1 = num;
  6002. +       wlen2 = 0;
  6003. +   }
  6004. +   if (wlen1) {
  6005. +       memcpy((irc->rxbuf.ringbuf + wp),
  6006. +           irc->rxbuf.buf, wlen1);
  6007. +       wp += wlen1;
  6008. +   }
  6009. +   if (wlen2) {
  6010. +       wp = 0;
  6011. +       memcpy((irc->rxbuf.ringbuf + wp),
  6012. +           (irc->rxbuf.buf + wlen1), wlen2);
  6013. +       wp += wlen2;
  6014. +   }
  6015. +   irc->rxbuf.wp = wp;
  6016. +
  6017. +   if (irc->rxbuf.wp >= IRUART_SW_RXRINGBUF_SIZE)
  6018. +       irc->rxbuf.wp -= IRUART_SW_RXRINGBUF_SIZE;
  6019. +
  6020. +   if (irc->rx_overflow != IRDA_OVERFLOW &&
  6021. +           (num == IRUART_SW_RXBUF_SIZE ||
  6022. +           (irc->bps == 115200 &&
  6023. +           (num == 128 || num == 256 || num == 384)))) {
  6024. +       printk(KERN_ERR DRV_NAME ": retry rxfer_start.\n");
  6025. +       spin_unlock_irqrestore(&irc->lock, flags);
  6026. +       irda_uart_rxfer_start(0);
  6027. +       spin_lock_irqsave(&irc->lock, flags);
  6028. +   } else {
  6029. +out:
  6030. +       /* Enable RXLEV */
  6031. +       irc->imr_reg |= BIT_RXLEV;
  6032. +       msm_uartdm_write(UARTDM_IMR, irc->imr_reg);
  6033. +   }
  6034. +   irc->condition_rx = 1;
  6035. +   wake_up_interruptible(&irc->wait_rx);
  6036. +   spin_unlock_irqrestore(&irc->lock, flags);
  6037. +}
  6038. +
  6039. +static void irda_uart_txfer_exec(unsigned long data)
  6040. +{
  6041. +   int rest;
  6042. +   unsigned long flags;
  6043. +
  6044. +   spin_lock_irqsave(&irc->lock, flags);
  6045. +
  6046. +   rest = irc->txbuf.num - irc->txbuf.ptr;
  6047. +   if (rest > 0) {
  6048. +       if (rest > IRUART_SW_TXBUF_SIZE)
  6049. +           rest = IRUART_SW_TXBUF_SIZE;
  6050. +       irc->txbox->src_row_addr = irc->txbuf.dmabase + irc->txbuf.ptr;
  6051. +       irc->txbox->num_rows =
  6052. +           ((rest + 15) >> 4 << 16) | (rest + 15) >> 4;
  6053. +       msm_dmov_enqueue_cmd(irc->pfdata->chan_uartdm_tx,
  6054. +                   &irc->txdmov_cmd);
  6055. +       msm_uartdm_write(UARTDM_NCF_TX, rest);
  6056. +       irc->txbuf.ptr += rest;
  6057. +   }
  6058. +
  6059. +   spin_unlock_irqrestore(&irc->lock, flags);
  6060. +}
  6061. +
  6062. +static irqreturn_t irda_uart_irq_handler(int irq, void *dev)
  6063. +{
  6064. +   u32 isr_reg;
  6065. +   unsigned long flags;
  6066. +
  6067. +   spin_lock_irqsave(&irc->lock, flags);
  6068. +
  6069. +   isr_reg = msm_uartdm_read(UARTDM_ISR);
  6070. +
  6071. +   /* TX Ready (TX completion) */
  6072. +   if (isr_reg & BIT_TX_READY) {
  6073. +       irc->imr_reg &= ~BIT_TX_READY;
  6074. +       msm_uartdm_write(UARTDM_IMR, irc->imr_reg);
  6075. +       msm_uartdm_write(UARTDM_CR, GCMD_RESET_TX_READY_INTERRUPT);
  6076. +       if (irc->txbuf.num - irc->txbuf.ptr) {
  6077. +           tasklet_schedule(&irc->tasklet_txfer);
  6078. +       } else {
  6079. +           u32 sr_reg = msm_uartdm_read(UARTDM_SR);
  6080. +           while (!(sr_reg & BIT_TXEMT)) {
  6081. +               udelay(1); /* delay 1us */
  6082. +               sr_reg = msm_uartdm_read(UARTDM_SR);
  6083. +           }
  6084. +
  6085. +           msm_uartdm_write(UARTDM_CR, BIT_UART_RX_EN);
  6086. +           irc->condition_tx = 1;
  6087. +           wake_up_interruptible(&irc->wait_tx);
  6088. +       }
  6089. +   }
  6090. +   /* RXLEV (1byte recognition)*/
  6091. +   if (isr_reg & BIT_RXLEV) {
  6092. +       irc->imr_reg &= ~BIT_RXLEV;
  6093. +       msm_uartdm_write(UARTDM_IMR, irc->imr_reg);
  6094. +       tasklet_schedule(&irc->tasklet_rxfer_s);
  6095. +   }
  6096. +   /* RX Stale (RXDM timeout)*/
  6097. +   if (isr_reg & BIT_RXSTALE) {
  6098. +       irc->imr_reg &= ~BIT_RXSTALE;
  6099. +       msm_uartdm_write(UARTDM_IMR, irc->imr_reg);
  6100. +       msm_dmov_flush(irc->pfdata->chan_uartdm_rx);
  6101. +   }
  6102. +
  6103. +   spin_unlock_irqrestore(&irc->lock, flags);
  6104. +
  6105. +   return IRQ_HANDLED;
  6106. +}
  6107. +
  6108. +static unsigned int irda_baudrate_set(unsigned int bps)
  6109. +{
  6110. +   unsigned long rxstale;
  6111. +   unsigned long iprdata;
  6112. +   u32           sr_reg;
  6113. +
  6114. +   /* check the transmitter under-runs. */
  6115. +   sr_reg = msm_uartdm_read(UARTDM_SR);
  6116. +   if (!(sr_reg&BIT_TXEMT))
  6117. +       msleep(1);
  6118. +   if (!(sr_reg&BIT_TXEMT))
  6119. +       return -EBUSY;
  6120. +
  6121. +   switch (bps) {
  6122. +   case B2400:
  6123. +       bps = 2400;
  6124. +       msm_uartdm_write(UARTDM_CSR, 0x33);
  6125. +       rxstale = 1;
  6126. +       break;
  6127. +   case B9600:
  6128. +       bps = 9600;
  6129. +       msm_uartdm_write(UARTDM_CSR, 0x55);
  6130. +       rxstale = 2;
  6131. +       break;
  6132. +   case B19200:
  6133. +       bps = 19200;
  6134. +       msm_uartdm_write(UARTDM_CSR, 0x77);
  6135. +       rxstale = 4;
  6136. +       break;
  6137. +   case B38400:
  6138. +       bps = 38400;
  6139. +       msm_uartdm_write(UARTDM_CSR, 0x99);
  6140. +       rxstale = 8;
  6141. +       break;
  6142. +   case B57600:
  6143. +       bps = 57600;
  6144. +       msm_uartdm_write(UARTDM_CSR, 0xaa);
  6145. +       rxstale = 16;
  6146. +       break;
  6147. +   case B115200:
  6148. +       bps = 115200;
  6149. +       msm_uartdm_write(UARTDM_CSR, 0xcc);
  6150. +       rxstale = 31;
  6151. +       break;
  6152. +   default:
  6153. +       /* default to 9600 */
  6154. +       printk(KERN_WARNING DRV_NAME
  6155. +       ": changed %d bps into 9600 bps of the default value.\n",
  6156. +           bps);
  6157. +       bps = 9600;
  6158. +       msm_uartdm_write(UARTDM_CSR, 0x55);
  6159. +       rxstale = 2;
  6160. +       break;
  6161. +   }
  6162. +
  6163. +   irc->bps = bps;
  6164. +   if (clk_set_rate(irc->clk_uartdm, IRUART_UARTDM_CLK(bps))) {
  6165. +       printk(KERN_WARNING DRV_NAME
  6166. +           ": error setting clock rate on UART\n");
  6167. +       return -EIO;
  6168. +   }
  6169. +
  6170. +   iprdata = rxstale & BIT_STALE_TIMEOUT_LSB;
  6171. +   iprdata |= BIT_STALE_TIMEOUT_MSB & (rxstale << 2);
  6172. +
  6173. +   msm_uartdm_write(UARTDM_IPR, iprdata);
  6174. +
  6175. +   return 0;
  6176. +}
  6177. +
  6178. +static int irda_uart_open(struct inode *inode, struct file *file)
  6179. +{
  6180. +   int ret;
  6181. +   u8 misc = 0x0;
  6182. +
  6183. +   down(&irc->sem);
  6184. +   printk(KERN_INFO DRV_NAME ": %s\n", __func__);
  6185. +
  6186. +   /* Check refcount */
  6187. +   if (irc->refcount > 0) {
  6188. +       irc->refcount++;
  6189. +       printk(KERN_INFO DRV_NAME
  6190. +           ": refirence counter count up(%d).\n", irc->refcount);
  6191. +       up(&irc->sem);
  6192. +       return 0;
  6193. +   }
  6194. +   /* PM8058-NFC Request */
  6195. +   irc->nfcdev = pm8058_nfc_request();
  6196. +   if (irc->nfcdev == NULL) {
  6197. +       printk(KERN_ERR DRV_NAME ": pm8058 nfc not found.\n");
  6198. +       ret = -ENODEV;
  6199. +       goto error_pm_nfc_request;
  6200. +   }
  6201. +
  6202. +   /* PM8058 UART MUX setting */
  6203. +   ret = pm8058_read(irc->nfcdev->pm_chip, SSBI_REG_ADDR_MISC, &misc, 1);
  6204. +   if (ret)
  6205. +       printk(KERN_ERR DRV_NAME
  6206. +           ": cannot read pm8058 UART MUX reg.\n");
  6207. +   else
  6208. +       printk(KERN_INFO DRV_NAME ": misc register = %x\n", misc);
  6209. +   misc &= PM8058_UART_MUX_MASK;
  6210. +   switch (misc) {
  6211. +   case PM8058_UART_MUX_NO:
  6212. +       pm8058_misc_control(irc->nfcdev->pm_chip,
  6213. +               PM8058_UART_MUX_MASK, PM8058_UART_MUX_3);
  6214. +       printk(KERN_INFO DRV_NAME
  6215. +           ": OK. UART MUX = neutral --> IrDA.\n");
  6216. +       break;
  6217. +   case PM8058_UART_MUX_1:
  6218. +       printk(KERN_ERR DRV_NAME ": Now, uart_mux = 1 (FeliCa)\n");
  6219. +       ret = -EBUSY;
  6220. +       goto err_set_uart_mux;
  6221. +   case PM8058_UART_MUX_2:
  6222. +       printk(KERN_ERR DRV_NAME ": Now, uart_mux = 2 (unknown)\n");
  6223. +       ret = -EBUSY;
  6224. +       goto err_set_uart_mux;
  6225. +   default:
  6226. +       printk(KERN_ERR DRV_NAME ": UART MUX unavaible.\n");
  6227. +       ret = -EIO;
  6228. +       goto err_set_uart_mux;
  6229. +   }
  6230. +
  6231. +   /* init IMR value */
  6232. +   irc->imr_reg = 0x0;
  6233. +
  6234. +   /* init wait queue */
  6235. +   init_waitqueue_head(&irc->wait_tx);
  6236. +   init_waitqueue_head(&irc->wait_rx);
  6237. +
  6238. +   /* init tasklet */
  6239. +   tasklet_init(&irc->tasklet_rxfer_s, irda_uart_rxfer_start, 0);
  6240. +   tasklet_init(&irc->tasklet_rxfer_e, irda_uart_rxfer_end,   0);
  6241. +   tasklet_init(&irc->tasklet_txfer,   irda_uart_txfer_exec,  0);
  6242. +
  6243. +   /* Register UARTDM IRQ */
  6244. +   ret = request_irq(irc->pfdata->irq_uartdm, irda_uart_irq_handler,
  6245. +               IRQF_TRIGGER_HIGH,  "irda_uart", irc);
  6246. +   if (ret) {
  6247. +       printk(KERN_ERR DRV_NAME ": request IRQ failed. (UARTDM)\n");
  6248. +       goto err_request_irq_uart;
  6249. +   }
  6250. +
  6251. +   /* UARTDM ioremap */
  6252. +   /* memory protection */
  6253. +   irc->iores_uartdm = request_mem_region((u32) irc->pfdata->paddr_uartdm,
  6254. +                       UARTDM_SIZE, "irda_uart");
  6255. +   if (!irc->iores_uartdm) {
  6256. +       printk(KERN_ERR DRV_NAME
  6257. +           ": UARTDM request_mem_region failed.\n");
  6258. +       ret = -EBUSY;
  6259. +       goto err_request_mem_region;
  6260. +   }
  6261. +   irc->vaddr_uartdm = ioremap_nocache((u32) irc->pfdata->paddr_uartdm,
  6262. +                       UARTDM_SIZE);
  6263. +   if (!irc->vaddr_uartdm) {
  6264. +       printk(KERN_ERR DRV_NAME ": UARTDM ioremap failed.\n");
  6265. +       ret = -ENOMEM;
  6266. +       goto err_ioremap_uartdm;
  6267. +   }
  6268. +
  6269. +   /* UARTDM clock set and start */
  6270. +   /* default 9600 bps */
  6271. +   irc->bps = 9600;
  6272. +   clk_set_rate(irc->clk_uartdm, IRUART_UARTDM_CLK(9600));
  6273. +   clk_enable(irc->clk_uartdm);
  6274. +   msm_uartdm_write(UARTDM_CSR, IRUART_DEF_BAUDRATE_CSR);
  6275. +
  6276. +   /* UARTDM register setting */
  6277. +   /* Data-stop-parity setting (MR2) */
  6278. +   msm_uartdm_write(UARTDM_MR2, IRUART_DATA_STOP_PARITY);
  6279. +
  6280. +   /* RX&TX wartermark setting */
  6281. +   msm_uartdm_write(UARTDM_TFWR, 0x0);
  6282. +   msm_uartdm_write(UARTDM_RFWR, 0x0);
  6283. +
  6284. +   /* Stale time-out setting */
  6285. +   msm_uartdm_write(UARTDM_IPR,
  6286. +           (IRUART_DEF_RXSTALE & BIT_STALE_TIMEOUT_LSB)
  6287. +           | ((IRUART_DEF_RXSTALE << 2) & BIT_STALE_TIMEOUT_MSB));
  6288. +
  6289. +   /* Enable TXDM and RXDM mode */
  6290. +   msm_uartdm_write(UARTDM_DMEN, BIT_RX_DM_EN|BIT_TX_DM_EN);
  6291. +
  6292. +   /* Enable the IRDA transceiver */
  6293. +   msm_uartdm_write(UARTDM_IRDA, IRUART_IRDA_EN);
  6294. +
  6295. +   /* TX DMOV mapping */
  6296. +   irc->txbox = dma_alloc_coherent(NULL, sizeof(dmov_box),
  6297. +                   &irc->mapped_txbox, GFP_KERNEL);
  6298. +   if (!irc->txbox) {
  6299. +       printk(KERN_ERR DRV_NAME ": no enough mem for TX DMOV(1).\n");
  6300. +       ret = -ENOMEM;
  6301. +       goto err_alloc_txbox;
  6302. +   }
  6303. +   irc->txbox_ptr = dma_alloc_coherent(NULL, sizeof(u32 *),
  6304. +                   &irc->mapped_txbox_ptr, GFP_KERNEL);
  6305. +   if (!irc->txbox_ptr) {
  6306. +       printk(KERN_ERR DRV_NAME ": no enough mem for TX DMOV(2).\n");
  6307. +       ret = -ENOMEM;
  6308. +       goto err_alloc_txbox_ptr;
  6309. +   }
  6310. +   *irc->txbox_ptr = CMD_PTR_LP | DMOV_CMD_ADDR(irc->mapped_txbox);
  6311. +   irc->txdmov_cmd.cmdptr = DMOV_CMD_ADDR(irc->mapped_txbox_ptr);
  6312. +   irc->txdmov_cmd.complete_func = irda_txdmov_callback;
  6313. +   irc->txdmov_cmd.cmdptr = DMOV_CMD_ADDR(irc->mapped_txbox_ptr);
  6314. +   irc->txbox->cmd =
  6315. +       CMD_LC
  6316. +       | CMD_DST_CRCI(irc->pfdata->crci_uartdm_tx) | CMD_MODE_BOX;
  6317. +   /* TX DMOV BOX command */
  6318. +   irc->txbox->src_row_addr = 0x0;
  6319. +   irc->txbox->dst_row_addr = (u32)irc->pfdata->paddr_uartdm + UARTDM_TF;
  6320. +   irc->txbox->src_dst_len = (UARTDM_BURST_SIZE<<16)|UARTDM_BURST_SIZE;
  6321. +   irc->txbox->num_rows = 0x0;
  6322. +   irc->txbox->row_offset = (UARTDM_BURST_SIZE<<16);
  6323. +
  6324. +   /* RX DMOV mapping */
  6325. +   irc->rxbox = dma_alloc_coherent(NULL, sizeof(dmov_box),
  6326. +                   &irc->mapped_rxbox, GFP_KERNEL);
  6327. +   if (!irc->rxbox) {
  6328. +       printk(KERN_ERR DRV_NAME ": no enough mem for RX DMOV(1).\n");
  6329. +       ret = -ENOMEM;
  6330. +       goto err_alloc_rxbox;
  6331. +   }
  6332. +   irc->rxbox_ptr = dma_alloc_coherent(NULL, sizeof(u32 *),
  6333. +                   &irc->mapped_rxbox_ptr, GFP_KERNEL);
  6334. +   if (!irc->rxbox_ptr) {
  6335. +       printk(KERN_ERR DRV_NAME ": no enough mem for RX DMOV(2).\n");
  6336. +       ret = -ENOMEM;
  6337. +       goto err_alloc_rxbox_ptr;
  6338. +   }
  6339. +   *irc->rxbox_ptr = CMD_PTR_LP | DMOV_CMD_ADDR(irc->mapped_rxbox);
  6340. +   irc->rxdmov_cmd.cmdptr = DMOV_CMD_ADDR(irc->mapped_rxbox_ptr);
  6341. +   irc->rxdmov_cmd.complete_func = irda_rxdmov_callback;
  6342. +   irc->rxdmov_cmd.cmdptr = DMOV_CMD_ADDR(irc->mapped_rxbox_ptr);
  6343. +   irc->rxbox->cmd =
  6344. +       CMD_LC
  6345. +       | CMD_SRC_CRCI(irc->pfdata->crci_uartdm_rx)
  6346. +       | CMD_MODE_BOX;
  6347. +   /* RX DMOV BOX command */
  6348. +   irc->rxbox->src_row_addr =
  6349. +       (u32)irc->pfdata->paddr_uartdm + UARTDM_RF;
  6350. +   irc->rxbox->dst_row_addr = 0x0;
  6351. +   irc->rxbox->src_dst_len = (UARTDM_BURST_SIZE<<16)|UARTDM_BURST_SIZE;
  6352. +   irc->rxbox->num_rows =
  6353. +       (IRUART_SW_RXBUF_SIZE >> 4 << 16) | IRUART_SW_RXBUF_SIZE >> 4;
  6354. +   irc->rxbox->row_offset = UARTDM_BURST_SIZE;
  6355. +
  6356. +   /* Enable Command Register Protection */
  6357. +   msm_uartdm_write(UARTDM_CR, GCMD_CR_PROTECTION_ENABLE);
  6358. +
  6359. +   /* Reset TX and RX */
  6360. +   msm_uartdm_write(UARTDM_CR, CCMD_RESET_RECEIVER);
  6361. +   msm_uartdm_write(UARTDM_CR, CCMD_RESET_TRANSMITTER);
  6362. +   msm_uartdm_write(UARTDM_CR, CCMD_RESET_ERROR_STATUS);
  6363. +   msm_uartdm_write(UARTDM_CR, CCMD_RESET_STALE_INTERRUPT);
  6364. +
  6365. +   /* Setting PM power on (Low) */
  6366. +   ret = pm8058_gpio_config(irc->pfdata->gpio_pow,
  6367. +                irc->pfdata->gpio_pwcfg_low);
  6368. +   if (ret) {
  6369. +       printk(KERN_ERR DRV_NAME ": pmic gpio write failed\n");
  6370. +       goto err_gpio_config;
  6371. +   }
  6372. +   /* Wait 200usec */
  6373. +   udelay(200);
  6374. +
  6375. +   /* Enable Transmitter and Receiver */
  6376. +   msm_uartdm_write(UARTDM_CR, BIT_UART_TX_EN);
  6377. +   msm_uartdm_write(UARTDM_CR, BIT_UART_RX_EN);
  6378. +
  6379. +   /* Clear UART SW buffer */
  6380. +   irda_txbuf_clear(&irc->txbuf);
  6381. +   irda_rxbuf_clear(&irc->rxbuf);
  6382. +
  6383. +   /* init Overflow flag */
  6384. +   irc->rx_overflow = IRDA_NORMAL;
  6385. +
  6386. +   /* Increment refcount */
  6387. +   irc->refcount++;
  6388. +
  6389. +   /* (state change)--> IRDA_UART_OPEN */
  6390. +   irc->state = IRDA_UART_OPEN;
  6391. +   irc->rx_state = IRDA_RX_IDLE;
  6392. +
  6393. +   printk(KERN_INFO DRV_NAME
  6394. +       ": succecssfly opened, refcount = %d\n", irc->refcount);
  6395. +
  6396. +   /* Activate RXLEV IRQ */
  6397. +   irc->imr_reg |= BIT_RXLEV;
  6398. +   msm_uartdm_write(UARTDM_IMR, irc->imr_reg);
  6399. +
  6400. +   up(&irc->sem);
  6401. +   return 0;
  6402. +
  6403. +/* Error handling */
  6404. +err_gpio_config:
  6405. +   dma_free_coherent(NULL,
  6406. +           sizeof(u32 *), irc->rxbox_ptr, irc->mapped_txbox_ptr);
  6407. +err_alloc_rxbox_ptr:
  6408. +   dma_free_coherent(NULL,
  6409. +           sizeof(dmov_box), irc->rxbox, irc->mapped_rxbox);
  6410. +err_alloc_rxbox:
  6411. +   dma_free_coherent(NULL,
  6412. +           sizeof(u32 *), irc->txbox_ptr, irc->mapped_txbox_ptr);
  6413. +err_alloc_txbox_ptr:
  6414. +   dma_free_coherent(NULL,
  6415. +           sizeof(dmov_box), irc->txbox, irc->mapped_txbox);
  6416. +err_alloc_txbox:
  6417. +   msm_uartdm_write(UARTDM_IRDA, IRUART_IRDA_DISABLE);
  6418. +   clk_disable(irc->clk_uartdm);
  6419. +   iounmap(irc->vaddr_uartdm);
  6420. +err_ioremap_uartdm:
  6421. +   release_mem_region((u32) irc->pfdata->paddr_uartdm, UARTDM_SIZE);
  6422. +err_request_mem_region:
  6423. +   free_irq(irc->pfdata->irq_uartdm, irc);
  6424. +err_request_irq_uart:
  6425. +   tasklet_kill(&irc->tasklet_rxfer_s);
  6426. +   tasklet_kill(&irc->tasklet_rxfer_e);
  6427. +   tasklet_kill(&irc->tasklet_txfer);
  6428. +   pm8058_misc_control(irc->nfcdev->pm_chip,
  6429. +               PM8058_UART_MUX_MASK, PM8058_UART_MUX_NO);
  6430. +err_set_uart_mux:
  6431. +error_pm_nfc_request:
  6432. +   up(&irc->sem);
  6433. +   return ret;
  6434. +}
  6435. +
  6436. +static int irda_uart_release(struct inode *inode, struct file *file)
  6437. +{
  6438. +   down(&irc->sem);
  6439. +   printk(KERN_INFO DRV_NAME ": %s\n", __func__);
  6440. +
  6441. +   /* Decrement refcount */
  6442. +   irc->refcount--;
  6443. +
  6444. +   /* Check refcount */
  6445. +   if (irc->refcount == 0) {
  6446. +       /* do discard flush */
  6447. +       if (irc->rx_state == IRDA_RX_START) {
  6448. +           irc->rx_state = IRDA_RX_IDLE;
  6449. +           msm_dmov_stop_cmd(irc->pfdata->chan_uartdm_rx,
  6450. +                       &irc->rxdmov_cmd, 0);
  6451. +       }
  6452. +
  6453. +       /* Deactivate RXLEV IRQ */
  6454. +       irc->imr_reg &= ~BIT_RXLEV;
  6455. +       msm_uartdm_write(UARTDM_IMR, irc->imr_reg);
  6456. +       /* (state change)--> IRDA_UART_OPEN */
  6457. +       irc->state = IRDA_UART_CLOSE;
  6458. +       /* Disable the IRDA transceiver */
  6459. +       msm_uartdm_write(UARTDM_IRDA, IRUART_IRDA_DISABLE);
  6460. +       /* Disable Transmitter and Receiver */
  6461. +       msm_uartdm_write(UARTDM_CR, BIT_UART_TX_DISABLE);
  6462. +       msm_uartdm_write(UARTDM_CR, BIT_UART_RX_DISABLE);
  6463. +
  6464. +       /* Desable TXDM and RXDM mode */
  6465. +       msm_uartdm_write(UARTDM_DMEN, IRUART_IRDA_DISABLE);
  6466. +
  6467. +       /* Wait 1usec */
  6468. +       udelay(1);
  6469. +       /* Setting PM power off (Hig) */
  6470. +       pm8058_gpio_config(irc->pfdata->gpio_pow,
  6471. +                  irc->pfdata->gpio_pwcfg_hig);
  6472. +
  6473. +       /* Clear UART SW buffer */
  6474. +       irda_txbuf_clear(&irc->txbuf);
  6475. +       irda_rxbuf_clear(&irc->rxbuf);
  6476. +       /* Reset TX and RX*/
  6477. +       msm_uartdm_write(UARTDM_CR, CCMD_RESET_RECEIVER);
  6478. +       msm_uartdm_write(UARTDM_CR, CCMD_RESET_TRANSMITTER);
  6479. +       msm_uartdm_write(UARTDM_CR, CCMD_RESET_ERROR_STATUS);
  6480. +       msm_uartdm_write(UARTDM_CR, CCMD_RESET_STALE_INTERRUPT);
  6481. +       /* Release DMOV data */
  6482. +       dma_free_coherent(NULL, sizeof(dmov_box),
  6483. +                   irc->txbox, irc->mapped_txbox);
  6484. +       dma_free_coherent(NULL, sizeof(dmov_box),
  6485. +                   irc->rxbox, irc->mapped_rxbox);
  6486. +       dma_free_coherent(NULL, sizeof(u32 *),
  6487. +                   irc->txbox_ptr, irc->mapped_txbox_ptr);
  6488. +       dma_free_coherent(NULL, sizeof(u32 *),
  6489. +                   irc->rxbox_ptr, irc->mapped_rxbox_ptr);
  6490. +       /* UARTDM clock stop */
  6491. +       clk_disable(irc->clk_uartdm);
  6492. +       /* UARTDM iounmap */
  6493. +       if (irc->iores_uartdm)
  6494. +           release_mem_region((u32) irc->pfdata->paddr_uartdm,
  6495. +                       UARTDM_SIZE);
  6496. +       iounmap(irc->vaddr_uartdm);
  6497. +       /* Remove IRQ for UARTDM */
  6498. +       free_irq(irc->pfdata->irq_uartdm, irc);
  6499. +       /* Remove tasklets for UARTDM */
  6500. +       tasklet_kill(&irc->tasklet_rxfer_s);
  6501. +       tasklet_kill(&irc->tasklet_rxfer_e);
  6502. +       tasklet_kill(&irc->tasklet_txfer);
  6503. +       /* PM8058 UART MUX reset */
  6504. +       pm8058_misc_control(irc->nfcdev->pm_chip,
  6505. +               PM8058_UART_MUX_MASK, PM8058_UART_MUX_NO);
  6506. +       {
  6507. +           u8 misc = 0x0;
  6508. +           int ret = pm8058_read(irc->nfcdev->pm_chip,
  6509. +                       SSBI_REG_ADDR_MISC, &misc, 1);
  6510. +           if (ret)
  6511. +               printk(KERN_ERR DRV_NAME
  6512. +                   ": cannot read pm8058 UART MUX reg.\n");
  6513. +           else
  6514. +               printk(KERN_INFO DRV_NAME
  6515. +                   ": misc register = %x\n", misc);
  6516. +       }
  6517. +   }
  6518. +   printk(KERN_INFO DRV_NAME ": Closed. Refcount = %d\n", irc->refcount);
  6519. +   up(&irc->sem);
  6520. +
  6521. +   return 0;
  6522. +}
  6523. +
  6524. +static ssize_t irda_uart_read(
  6525. +   struct file *file, char __user *buf,
  6526. +   size_t count, loff_t *offset)
  6527. +{
  6528. +   int cnt, rest, srest1, srest2;
  6529. +   unsigned long flags;
  6530. +   int ret;
  6531. +
  6532. +   down(&irc->sem);
  6533. +
  6534. +   if (irc->state != IRDA_UART_OPEN) {
  6535. +       ret = -EHOSTUNREACH;
  6536. +       goto err_out;
  6537. +   }
  6538. +
  6539. +   spin_lock_irqsave(&irc->lock, flags);
  6540. +   ret = (irc->rx_overflow == IRDA_NORMAL)
  6541. +       && (irc->rxbuf.wp == irc->rxbuf.rp);
  6542. +   if (ret)
  6543. +       irc->condition_rx = 0;
  6544. +   spin_unlock_irqrestore(&irc->lock, flags);
  6545. +
  6546. +   cnt = 0;
  6547. +   if (ret) {
  6548. +       ret = wait_event_interruptible(irc->wait_rx, irc->condition_rx);
  6549. +       irc->condition_rx = 0;
  6550. +
  6551. +       spin_lock_irqsave(&irc->lock, flags);
  6552. +       ret = (irc->rx_overflow == IRDA_NORMAL)
  6553. +           && (irc->rxbuf.wp == irc->rxbuf.rp);
  6554. +       spin_unlock_irqrestore(&irc->lock, flags);
  6555. +
  6556. +       if (ret)
  6557. +           goto out;
  6558. +   }
  6559. +
  6560. +   spin_lock_irqsave(&irc->lock, flags);
  6561. +   if (irc->rxbuf.wp > irc->rxbuf.rp) {
  6562. +       srest1 = irc->rxbuf.wp - irc->rxbuf.rp;
  6563. +       srest2 = 0;
  6564. +   } else {
  6565. +       srest1 = IRUART_SW_RXRINGBUF_SIZE - irc->rxbuf.rp;
  6566. +       srest2 = irc->rxbuf.wp;
  6567. +   }
  6568. +   rest = count - cnt;
  6569. +   spin_unlock_irqrestore(&irc->lock, flags);
  6570. +
  6571. +   if (rest > srest1)
  6572. +       rest = srest1;
  6573. +   ret = copy_to_user(buf + cnt,
  6574. +               (irc->rxbuf.ringbuf + irc->rxbuf.rp), rest);
  6575. +   if (ret) {
  6576. +       ret = -EFAULT;
  6577. +       goto err_out;
  6578. +   }
  6579. +
  6580. +   spin_lock_irqsave(&irc->lock, flags);
  6581. +   /* Update RX buf status */
  6582. +   irc->rxbuf.rp += rest;
  6583. +   if (irc->rxbuf.rp >= IRUART_SW_RXRINGBUF_SIZE)
  6584. +       irc->rxbuf.rp -= IRUART_SW_RXRINGBUF_SIZE;
  6585. +   cnt += rest;
  6586. +   spin_unlock_irqrestore(&irc->lock, flags);
  6587. +
  6588. +   rest = count - cnt;
  6589. +   if (!rest || !srest2)
  6590. +       goto out;
  6591. +   if (rest > srest2)
  6592. +       rest = srest2;
  6593. +   ret = copy_to_user(buf + cnt,
  6594. +               (irc->rxbuf.ringbuf + irc->rxbuf.rp), rest);
  6595. +   if (ret) {
  6596. +       ret = -EFAULT;
  6597. +       goto err_out;
  6598. +   }
  6599. +
  6600. +   spin_lock_irqsave(&irc->lock, flags);
  6601. +   /* Update RX buf status */
  6602. +   irc->rxbuf.rp += rest;
  6603. +   cnt += rest;
  6604. +   spin_unlock_irqrestore(&irc->lock, flags);
  6605. +
  6606. +out:
  6607. +   irc->rx_overflow = IRDA_NORMAL;
  6608. +
  6609. +   up(&irc->sem);
  6610. +   return cnt;
  6611. +
  6612. +err_out:
  6613. +   printk(KERN_ERR DRV_NAME ": %s error(%d)\n", __func__, ret);
  6614. +   up(&irc->sem);
  6615. +   return ret;
  6616. +}
  6617. +
  6618. +static ssize_t irda_uart_write(
  6619. +   struct file *file, const char __user *buf, size_t count, loff_t *offset)
  6620. +{
  6621. +   int ret;
  6622. +
  6623. +   down(&irc->sem);
  6624. +
  6625. +   if (irc->state != IRDA_UART_OPEN) {
  6626. +       printk(KERN_ERR DRV_NAME
  6627. +           ": inconsistent state(%d).\n", irc->state);
  6628. +       ret = -EHOSTUNREACH;
  6629. +       goto err_out;
  6630. +   }
  6631. +
  6632. +   if (count > IRUART_SW_TXBUF_SIZE) {
  6633. +       printk(KERN_ERR DRV_NAME
  6634. +           ": too many characters for write(%d).\n", count);
  6635. +       ret = -EINVAL;
  6636. +       goto err_out;
  6637. +   }
  6638. +
  6639. +   irda_txbuf_clear(&irc->txbuf);
  6640. +
  6641. +   if (copy_from_user(irc->txbuf.buf, buf, count)) {
  6642. +       ret = -EFAULT;
  6643. +       goto err_out;
  6644. +   }
  6645. +
  6646. +   irc->txbuf.num = count;
  6647. +
  6648. +   irc->condition_tx = 0;
  6649. +   msm_uartdm_write(UARTDM_CR, BIT_UART_RX_DISABLE);
  6650. +
  6651. +   irda_uart_txfer_exec(0);
  6652. +
  6653. +   if (!irc->condition_tx)
  6654. +       ret = wait_event_interruptible(irc->wait_tx, irc->condition_tx);
  6655. +   irc->condition_tx = 0;
  6656. +
  6657. +   up(&irc->sem);
  6658. +   return irc->txbuf.num;
  6659. +
  6660. +err_out:
  6661. +   up(&irc->sem);
  6662. +   return ret;
  6663. +}
  6664. +
  6665. +static unsigned int irda_uart_poll(
  6666. +   struct file *file, struct poll_table_struct *wait)
  6667. +{
  6668. +   unsigned long flags;
  6669. +   int           ret;
  6670. +   unsigned int  mask = 0;
  6671. +
  6672. +   down(&irc->sem);
  6673. +
  6674. +   if (irc->state != IRDA_UART_OPEN) {
  6675. +       mask = POLLERR;
  6676. +       goto out;
  6677. +   }
  6678. +
  6679. +   poll_wait(file, &irc->wait_rx, wait);
  6680. +   spin_lock_irqsave(&irc->lock, flags);
  6681. +   ret = (irc->rx_overflow == IRDA_NORMAL)
  6682. +       && (irc->rxbuf.wp == irc->rxbuf.rp);
  6683. +   if (!ret)
  6684. +       mask = POLLIN | POLLRDNORM;
  6685. +   mask |= POLLOUT | POLLWRNORM;
  6686. +   spin_unlock_irqrestore(&irc->lock, flags);
  6687. +out:
  6688. +   up(&irc->sem);
  6689. +   return mask;
  6690. +}
  6691. +
  6692. +#define IRUART_IOCTRL_BAUDRATE 0x0e000002
  6693. +#define IRUART_IOCTRL_QRYINFRM 0x0e000005
  6694. +static int irda_uart_ioctl(
  6695. +   struct inode *inode, struct file *file,
  6696. +   unsigned int cmd, unsigned long arg)
  6697. +{
  6698. +   int ret;
  6699. +
  6700. +   down(&irc->sem);
  6701. +
  6702. +   switch (cmd) {
  6703. +   case IRUART_IOCTRL_BAUDRATE:
  6704. +       ret = irda_baudrate_set((unsigned int)arg);
  6705. +       if (ret) {
  6706. +           printk(KERN_ERR DRV_NAME ": baudrate set failed.\n");
  6707. +           goto err_out;
  6708. +       }
  6709. +       break;
  6710. +   default:
  6711. +       printk(KERN_ERR DRV_NAME ": Error. Unsupported IOCTL.\n");
  6712. +       ret = -ENOTTY;
  6713. +       goto err_out;
  6714. +   }
  6715. +
  6716. +   up(&irc->sem);
  6717. +   return 0;
  6718. +
  6719. +err_out:
  6720. +   up(&irc->sem);
  6721. +   return ret;
  6722. +}
  6723. +
  6724. +static const struct file_operations irc_fops = {
  6725. +   .owner      = THIS_MODULE,
  6726. +   .read       = irda_uart_read,
  6727. +   .write      = irda_uart_write,
  6728. +   .poll       = irda_uart_poll,
  6729. +   .ioctl      = irda_uart_ioctl,
  6730. +   .open       = irda_uart_open,
  6731. +   .release    = irda_uart_release,
  6732. +};
  6733. +
  6734. +static struct miscdevice irda_uart_device = {
  6735. +   .minor = MISC_DYNAMIC_MINOR,
  6736. +   .name = "irda_uart",
  6737. +   .fops = &irc_fops,
  6738. +};
  6739. +
  6740. +static int __init irda_probe(struct platform_device *pdev)
  6741. +{
  6742. +   int ret;
  6743. +
  6744. +   irc = kzalloc(sizeof(struct irda_driver_data), GFP_KERNEL);
  6745. +   if (!irc) {
  6746. +       printk(KERN_ERR DRV_NAME ": could not allocate memory.\n");
  6747. +       ret = -ENOMEM;
  6748. +       goto error_alloc_driver_data;
  6749. +   }
  6750. +
  6751. +   irc->pfdata = pdev->dev.platform_data;
  6752. +
  6753. +   /* GPIO Setting */
  6754. +   ret = irc->pfdata->gpio_init();
  6755. +   if (ret && ret != -EBUSY) {
  6756. +       printk(KERN_ERR DRV_NAME ": gpio initialize failed.\n");
  6757. +       ret = -EIO;
  6758. +       goto error_gpio_init;
  6759. +   }
  6760. +
  6761. +   /* Platform Clock */
  6762. +   irc->clk_uartdm = clk_get(irc->pfdata->clk_dev, irc->pfdata->clk_str);
  6763. +   if (IS_ERR(irc->clk_uartdm)) {
  6764. +       printk(KERN_ERR DRV_NAME ": clock assignment failed.\n");
  6765. +       ret = -ENODEV;
  6766. +       goto error_get_platform_clock;
  6767. +   }
  6768. +   /* init Ref count */
  6769. +   irc->refcount = 0;
  6770. +
  6771. +   /* Alloc RX ring buffer */
  6772. +   irc->rxbuf.ringbuf = kzalloc(sizeof(u8)*(
  6773. +                   IRUART_SW_RXRINGBUF_SIZE
  6774. +                   + IRUART_SW_RXBUF_SIZE),
  6775. +               GFP_KERNEL);
  6776. +   if (!irc->rxbuf.ringbuf) {
  6777. +       printk(KERN_ERR DRV_NAME
  6778. +           ": could not allocate memory for RX ring buffer.\n");
  6779. +       ret = -ENOMEM;
  6780. +       goto error_alloc_rx_ringbuf;
  6781. +   }
  6782. +
  6783. +   /* Alloc TX SW Buffer */
  6784. +   irc->txbuf.buf = dma_alloc_coherent(NULL,
  6785. +                   sizeof(u8)*IRUART_SW_TXBUF_SIZE,
  6786. +                   &irc->txbuf.dmabase, GFP_KERNEL);
  6787. +   if (!irc->txbuf.buf) {
  6788. +       printk(KERN_ERR DRV_NAME ": no enough mem for TXbuf.\n");
  6789. +       ret = -ENOMEM;
  6790. +       goto err_alloc_tx_buffer;
  6791. +   }
  6792. +
  6793. +   /* Alloc RX SW Buffer */
  6794. +   irc->rxbuf.buf = dma_alloc_coherent(NULL,
  6795. +                   sizeof(u8)*IRUART_SW_RXBUF_SIZE,
  6796. +                   &irc->rxbuf.dmabase, GFP_KERNEL);
  6797. +   if (!irc->rxbuf.buf) {
  6798. +       printk(KERN_ERR DRV_NAME ": no enough mem for RXbuf.\n");
  6799. +       ret = -ENOMEM;
  6800. +       goto err_alloc_rx_buffer;
  6801. +   }
  6802. +
  6803. +   irc->rx_overflow = IRDA_NORMAL;
  6804. +
  6805. +   if (misc_register(&irda_uart_device)) {
  6806. +       printk(KERN_ERR DRV_NAME ": cannot register /dev/irda.\n");
  6807. +       ret = -EACCES;
  6808. +       goto err_register_uart_device;
  6809. +   }
  6810. +
  6811. +   sema_init(&irc->sem, 1);
  6812. +   spin_lock_init(&irc->lock);
  6813. +
  6814. +   irc->state = IRDA_UART_CLOSE;
  6815. +
  6816. +   return 0;
  6817. +
  6818. +/* error handling */
  6819. +err_register_uart_device:
  6820. +   dma_free_coherent(NULL, sizeof(u8)*IRUART_SW_RXBUF_SIZE,
  6821. +               irc->rxbuf.buf, irc->rxbuf.dmabase);
  6822. +err_alloc_rx_buffer:
  6823. +   dma_free_coherent(NULL, sizeof(u8)*IRUART_SW_TXBUF_SIZE,
  6824. +               irc->txbuf.buf, irc->txbuf.dmabase);
  6825. +err_alloc_tx_buffer:
  6826. +   kfree(irc->rxbuf.ringbuf);
  6827. +error_alloc_rx_ringbuf:
  6828. +error_get_platform_clock:
  6829. +error_gpio_init:
  6830. +   kfree(irc);
  6831. +error_alloc_driver_data:
  6832. +   return ret;
  6833. +}
  6834. +
  6835. +static int __devexit irda_remove(struct platform_device *pdev)
  6836. +{
  6837. +   printk(KERN_INFO DRV_NAME ": %s\n", __func__);
  6838. +
  6839. +   misc_deregister(&irda_uart_device);
  6840. +
  6841. +   dma_free_coherent(NULL, sizeof(u8)*IRUART_SW_TXBUF_SIZE,
  6842. +               irc->txbuf.buf, irc->txbuf.dmabase);
  6843. +   dma_free_coherent(NULL, sizeof(u8)*IRUART_SW_RXBUF_SIZE,
  6844. +               irc->rxbuf.buf, irc->rxbuf.dmabase);
  6845. +   kfree(irc);
  6846. +   return 0;
  6847. +}
  6848. +
  6849. +static int irda_suspend(struct platform_device *pdev,
  6850. +             pm_message_t message)
  6851. +{
  6852. +   printk(KERN_INFO DRV_NAME ": %s\n", __func__);
  6853. +   return 0;
  6854. +}
  6855. +
  6856. +static int irda_resume(struct platform_device *pdev)
  6857. +{
  6858. +   printk(KERN_INFO DRV_NAME ": %s\n", __func__);
  6859. +   return 0;
  6860. +}
  6861. +
  6862. +static struct platform_driver semc_msm_irda = {
  6863. +   .probe      = irda_probe,
  6864. +   .remove     = irda_remove,
  6865. +   .suspend    = irda_suspend,
  6866. +   .resume     = irda_resume,
  6867. +   .driver     = {
  6868. +       .name       = "semc-msm-irda",
  6869. +       .owner      = THIS_MODULE,
  6870. +   },
  6871. +};
  6872. +
  6873. +static int __init irda_init(void)
  6874. +{
  6875. +   int ret;
  6876. +   printk(KERN_INFO DRV_NAME ": %s\n", __func__);
  6877. +   ret = platform_driver_register(&semc_msm_irda);
  6878. +
  6879. +   return ret;
  6880. +}
  6881. +
  6882. +static void __exit irda_exit(void)
  6883. +{
  6884. +   printk(KERN_INFO DRV_NAME ": %s\n", __func__);
  6885. +   platform_driver_unregister(&semc_msm_irda);
  6886. +}
  6887. +
  6888. +module_init(irda_init);
  6889. +module_exit(irda_exit);
  6890. +
  6891. +MODULE_VERSION(DRV_VERSION);
  6892. +MODULE_AUTHOR("Yoshida Manabu <[email protected]>");
  6893. +MODULE_DESCRIPTION("SEMC MSM IrDA Driver");
  6894. +MODULE_LICENSE("GPL");
  6895. diff -ruN a/4.1.B.0.431//vendor/semc/hardware/irda/semc_msm_irda.h b/4.1.B.0.479//vendor/semc/hardware/irda/semc_msm_irda.h
  6896. --- a/4.1.B.0.431//vendor/semc/hardware/irda/semc_msm_irda.h    1970-01-01 09:00:00.000000000 +0900
  6897. +++ b/4.1.B.0.479//vendor/semc/hardware/irda/semc_msm_irda.h    2012-06-25 19:30:44.000000000 +0900
  6898. @@ -0,0 +1,55 @@
  6899. +/* drivers/serial/semc_irda/semc_msm_irda.h
  6900. + *
  6901. + * Copyright (C) 2011 Sony Ericsson Mobile Communications AB.
  6902. + *
  6903. + * Author: Manabu Yoshida <[email protected]>
  6904. + *
  6905. + * This program is free software; you can redistribute it and/or modify
  6906. + * it under the terms of the GNU General Public License version 2, as
  6907. + * published by the Free Software Foundation; either version 2
  6908. + * of the License, or (at your option) any later version.
  6909. + */
  6910. +
  6911. +#ifndef _SEMC_MSM_IRDA_H_
  6912. +#define _SEMC_MSM_IRDA_H_
  6913. +
  6914. +/* IrDA UART SW buffer settings */
  6915. +#define IRUART_SW_TXBUF_SIZE UART_XMIT_SIZE
  6916. +#define IRUART_SW_RXBUF_SIZE 512
  6917. +#define IRUART_SW_RXRINGBUF_SIZE (IRUART_SW_TXBUF_SIZE*2)
  6918. +
  6919. +/* SEMC MSM IrDA driver - Platform data */
  6920. +struct irda_platform_data {
  6921. +   int gpio_pow;
  6922. +   struct pm8058_gpio *gpio_pwcfg_low;
  6923. +   struct pm8058_gpio *gpio_pwcfg_hig;
  6924. +
  6925. +   u32 paddr_uartdm;
  6926. +   int irq_uartdm;
  6927. +   int chan_uartdm_tx;
  6928. +   int crci_uartdm_tx;
  6929. +   int chan_uartdm_rx;
  6930. +   int crci_uartdm_rx;
  6931. +   char clk_str[12];
  6932. +   struct device *clk_dev;
  6933. +   int (*gpio_init)(void);
  6934. +};
  6935. +
  6936. +struct irtxbuf_all {
  6937. +   int ptr;
  6938. +   int num;
  6939. +   u8 *buf;
  6940. +   dma_addr_t dmabase;
  6941. +};
  6942. +
  6943. +struct irrxbuf_all {
  6944. +   /* read buffer */
  6945. +   int wp;
  6946. +   int rp;
  6947. +   u8 *ringbuf;
  6948. +   /* dma buffer */
  6949. +   u8 *buf;
  6950. +   dma_addr_t dmabase;
  6951. +};
  6952. +
  6953. +#endif
  6954. diff -ruN a/4.1.B.0.431//vendor/ti/wlan/compat-wireless-wl12xx/drivers/net/wireless/wl12xx/boot.c b/4.1.B.0.479//vendor/ti/wlan/compat-wireless-wl12xx/drivers/net/wireless/wl12xx/boot.c
  6955. --- a/4.1.B.0.431//vendor/ti/wlan/compat-wireless-wl12xx/drivers/net/wireless/wl12xx/boot.c 2012-05-25 19:07:14.000000000 +0900
  6956. +++ b/4.1.B.0.479//vendor/ti/wlan/compat-wireless-wl12xx/drivers/net/wireless/wl12xx/boot.c 2012-06-25 19:47:11.000000000 +0900
  6957. @@ -2,6 +2,7 @@
  6958.   * This file is part of wl1271
  6959.   *
  6960.   * Copyright (C) 2008-2010 Nokia Corporation
  6961. + * Copyright (C) 2012 Sony Mobile Communications AB
  6962.   *
  6963.   * Contact: Luciano Coelho <[email protected]>
  6964.   *
  6965. @@ -472,6 +473,7 @@
  6966.  
  6967.     /* unmask required mbox events  */
  6968.     wl->event_mask = BSS_LOSE_EVENT_ID |
  6969. +       REGAINED_BSS_EVENT_ID |
  6970.         SCAN_COMPLETE_EVENT_ID |
  6971.         PS_REPORT_EVENT_ID |
  6972.         DISCONNECT_EVENT_COMPLETE_ID |
  6973. diff -ruN a/4.1.B.0.431//vendor/ti/wlan/compat-wireless-wl12xx/drivers/net/wireless/wl12xx/event.c b/4.1.B.0.479//vendor/ti/wlan/compat-wireless-wl12xx/drivers/net/wireless/wl12xx/event.c
  6974. --- a/4.1.B.0.431//vendor/ti/wlan/compat-wireless-wl12xx/drivers/net/wireless/wl12xx/event.c    2012-06-10 23:35:50.000000000 +0900
  6975. +++ b/4.1.B.0.479//vendor/ti/wlan/compat-wireless-wl12xx/drivers/net/wireless/wl12xx/event.c    2012-06-25 19:47:11.000000000 +0900
  6976. @@ -129,8 +129,7 @@
  6977.  }
  6978.  
  6979.  static int wl1271_event_ps_report(struct wl1271 *wl,
  6980. -                 struct event_mailbox *mbox,
  6981. -                 bool *beacon_loss)
  6982. +                 struct event_mailbox *mbox)
  6983.  {
  6984.     int ret = 0;
  6985.     u32 total_retries = wl->conf.conn.psm_entry_retries;
  6986. @@ -157,7 +156,7 @@
  6987.         } else {
  6988.             wl1271_info("No ack to nullfunc from AP.");
  6989.             wl->psm_entry_retry = 0;
  6990. -           *beacon_loss = true;
  6991. +           ieee80211_connection_loss(wl->vif);
  6992.         }
  6993.         break;
  6994.     case EVENT_ENTER_POWER_SAVE_SUCCESS:
  6995. @@ -255,7 +254,6 @@
  6996.  {
  6997.     int ret;
  6998.     u32 vector;
  6999. -   bool beacon_loss = false;
  7000.     bool is_ap = (wl->bss_type == BSS_TYPE_AP_BSS);
  7001.     bool disconnect_sta = false;
  7002.     unsigned long sta_bitmap = 0;
  7003. @@ -301,26 +299,37 @@
  7004.             timeout = 500;
  7005.         ieee80211_set_dyn_ps_timeout(wl->vif, timeout);
  7006.     }
  7007. -  
  7008. +
  7009.     /*
  7010. -    * The BSS_LOSE_EVENT_ID is only needed while psm (and hence beacon
  7011. -    * filtering) is enabled. Without PSM, the stack will receive all
  7012. -    * beacons and can detect beacon loss by itself.
  7013. -    *
  7014. -    * As there's possibility that the driver disables PSM before receiving
  7015. -    * BSS_LOSE_EVENT, beacon loss has to be reported to the stack.
  7016. -    *
  7017. +    * We are HW_MONITOR device. On beacon loss - queue
  7018. +    * connection loss work. Cancel it on REGAINED event.
  7019.      */
  7020.     if ((vector & BSS_LOSE_EVENT_ID) && !is_ap) {
  7021. +       int delay = wl->conf.conn.synch_fail_thold *
  7022. +                   wl->conf.conn.bss_lose_timeout;
  7023.         wl1271_info("Beacon loss detected.");
  7024.  
  7025. -       /* indicate to the stack, that beacons have been lost */
  7026. -       beacon_loss = true;
  7027. +       /*
  7028. +        * if the work is already queued, it should take place. We
  7029. +        * don't want to delay the connection loss indication
  7030. +        * any more.
  7031. +        */
  7032. +       ieee80211_queue_delayed_work(wl->hw, &wl->connection_loss_work,
  7033. +                   msecs_to_jiffies(delay));
  7034. +   }
  7035. +
  7036. +   if ((vector & REGAINED_BSS_EVENT_ID) && !is_ap) {
  7037. +       wl1271_info("Beacon regained.");
  7038. +       cancel_delayed_work(&wl->connection_loss_work);
  7039. +
  7040. +       /* sanity check - we can't lose and gain the beacon together */
  7041. +       WARN(vector & BSS_LOSE_EVENT_ID,
  7042. +            "Concurrent beacon loss and gain from FW");
  7043.     }
  7044.  
  7045.     if ((vector & PS_REPORT_EVENT_ID) && !is_ap) {
  7046.         wl1271_debug(DEBUG_EVENT, "PS_REPORT_EVENT");
  7047. -       ret = wl1271_event_ps_report(wl, mbox, &beacon_loss);
  7048. +       ret = wl1271_event_ps_report(wl, mbox);
  7049.         if (ret < 0)
  7050.             return ret;
  7051.     }
  7052. @@ -409,9 +418,6 @@
  7053.         }
  7054.     }
  7055.  
  7056. -   if (wl->vif && beacon_loss)
  7057. -       ieee80211_connection_loss(wl->vif);
  7058. -
  7059.     return 0;
  7060.  }
  7061.  
  7062. diff -ruN a/4.1.B.0.431//vendor/ti/wlan/compat-wireless-wl12xx/drivers/net/wireless/wl12xx/main.c b/4.1.B.0.479//vendor/ti/wlan/compat-wireless-wl12xx/drivers/net/wireless/wl12xx/main.c
  7063. --- a/4.1.B.0.431//vendor/ti/wlan/compat-wireless-wl12xx/drivers/net/wireless/wl12xx/main.c 2012-06-10 23:35:50.000000000 +0900
  7064. +++ b/4.1.B.0.479//vendor/ti/wlan/compat-wireless-wl12xx/drivers/net/wireless/wl12xx/main.c 2012-06-25 19:47:11.000000000 +0900
  7065. @@ -2346,6 +2346,7 @@
  7066.     cancel_delayed_work_sync(&wl->pspoll_work);
  7067.     cancel_work_sync(&wl->ap_start_work);
  7068.     cancel_delayed_work_sync(&wl->elp_work);
  7069. +   cancel_delayed_work_sync(&wl->connection_loss_work);
  7070.  
  7071.     mutex_lock(&wl->mutex);
  7072.  
  7073. @@ -4223,6 +4224,13 @@
  7074.     wl1271_debug(DEBUG_MAC80211, "mac80211 bss info changed 0x%x",
  7075.              (int)changed);
  7076.  
  7077. +   /*
  7078. +    * make sure to cancel pending disconnections if our association
  7079. +    * state changed
  7080. +    */
  7081. +   if (!is_ap && (changed & BSS_CHANGED_ASSOC))
  7082. +       cancel_delayed_work_sync(&wl->connection_loss_work);
  7083. +
  7084.     mutex_lock(&wl->mutex);
  7085.  
  7086.     if (unlikely(wl->state == WL1271_STATE_OFF))
  7087. @@ -5167,6 +5175,30 @@
  7088.     .read = wl1271_sysfs_read_fwlog,
  7089.  };
  7090.  
  7091. +void wl1271_connection_loss_work(struct work_struct *work)
  7092. +{
  7093. +   struct delayed_work *dwork;
  7094. +   struct wl1271 *wl;
  7095. +
  7096. +   dwork = container_of(work, struct delayed_work, work);
  7097. +   wl = container_of(dwork, struct wl1271, connection_loss_work);
  7098. +
  7099. +   wl1271_info("Connection loss work.");
  7100. +
  7101. +   mutex_lock(&wl->mutex);
  7102. +
  7103. +   if (unlikely(wl->state == WL1271_STATE_OFF))
  7104. +       goto out;
  7105. +
  7106. +   if (!test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags))
  7107. +       goto out;
  7108. +
  7109. +   /* Call mac80211 connection loss */
  7110. +   ieee80211_connection_loss(wl->vif);
  7111. +out:
  7112. +   mutex_unlock(&wl->mutex);
  7113. +}
  7114. +
  7115.  int wl1271_register_hw(struct wl1271 *wl)
  7116.  {
  7117.     int ret;
  7118. @@ -5363,6 +5395,7 @@
  7119.           wl1271_rx_streaming_disable_work);
  7120.     INIT_WORK(&wl->ap_start_work,
  7121.           wl12xx_ap_start_work);
  7122. +   INIT_DELAYED_WORK(&wl->connection_loss_work, wl1271_connection_loss_work);
  7123.  
  7124.     wl->freezable_wq = create_freezable_workqueue("wl12xx_wq");
  7125.     if (!wl->freezable_wq) {
  7126. diff -ruN a/4.1.B.0.431//vendor/ti/wlan/compat-wireless-wl12xx/drivers/net/wireless/wl12xx/wl12xx.h b/4.1.B.0.479//vendor/ti/wlan/compat-wireless-wl12xx/drivers/net/wireless/wl12xx/wl12xx.h
  7127. --- a/4.1.B.0.431//vendor/ti/wlan/compat-wireless-wl12xx/drivers/net/wireless/wl12xx/wl12xx.h   2012-06-10 23:35:50.000000000 +0900
  7128. +++ b/4.1.B.0.479//vendor/ti/wlan/compat-wireless-wl12xx/drivers/net/wireless/wl12xx/wl12xx.h   2012-06-25 19:47:11.000000000 +0900
  7129. @@ -606,6 +606,9 @@
  7130.     /* Beaconing interval (needed for ad-hoc) */
  7131.     u32 beacon_int;
  7132.  
  7133. +   /* Connection loss work */
  7134. +   struct delayed_work connection_loss_work;
  7135. +
  7136.     /* Default key (for WEP) */
  7137.     u32 default_key;
Advertisement
Add Comment
Please, Sign In to add comment