From b79ebb040bb76df85c426e5a7d8a78f6b3461adc Mon Sep 17 00:00:00 2001 From: Kibum Kim Date: Sat, 7 Jan 2012 00:44:35 +0900 Subject: [PATCH] Git init --- AUTHORS | 2 + CMakeLists.txt | 88 + LICENSE | 204 +++ SLP_devman_PG.h | 353 ++++ TC/build.sh | 20 + TC/execute.sh | 19 + TC/tet_code | 12 + TC/tet_scen | 7 + TC/tetbuild.cfg | 3 + TC/tetclean.cfg | 2 + TC/tetexec.cfg | 1 + TC/unit/Makefile | 42 + TC/unit/tc_gen.sh | 28 + TC/unit/tslist | 19 + TC/unit/utc_MODULE_API_func.c.in | 64 + TC/unit/utc_SystemFW_device_get_battery_pct_func.c | 64 + TC/unit/utc_SystemFW_device_get_display_brt_func.c | 66 + .../utc_SystemFW_device_get_display_gamma_func.c | 66 + TC/unit/utc_SystemFW_device_get_max_brt_func.c | 66 + TC/unit/utc_SystemFW_device_get_property_func.c | 69 + TC/unit/utc_SystemFW_device_haptic_close_func.c | 78 + ...SystemFW_device_haptic_get_file_duration_func.c | 84 + ...temFW_device_haptic_get_pattern_duration_func.c | 82 + TC/unit/utc_SystemFW_device_haptic_open_func.c | 71 + .../utc_SystemFW_device_haptic_play_file_func.c | 82 + ...utc_SystemFW_device_haptic_play_monotone_func.c | 79 + .../utc_SystemFW_device_haptic_play_pattern_func.c | 81 + .../utc_SystemFW_device_haptic_stop_play_func.c | 101 ++ TC/unit/utc_SystemFW_device_is_battery_full_func.c | 66 + .../utc_SystemFW_device_release_brt_ctrl_func.c | 73 + .../utc_SystemFW_device_release_gamma_ctrl_func.c | 67 + TC/unit/utc_SystemFW_device_set_display_brt_func.c | 65 + .../utc_SystemFW_device_set_display_gamma_func.c | 65 + TC/unit/utc_SystemFW_device_set_property_func.c | 68 + debian/changelog | 23 + debian/compat | 1 + debian/control | 34 + debian/dirs | 2 + debian/docs | 1 + debian/libdevman-0.install.in | 4 + debian/libdevman-0.postinst.in | 6 + debian/libdevman-0.postrm.in | 2 + debian/libdevman-dev.install.in | 3 + debian/libdevman-haptic-dev.install.in | 2 + debian/rules | 134 ++ device_engine.c | 242 +++ device_engine.h | 50 + device_generic.h | 60 + device_haptic.c | 1852 ++++++++++++++++++++ device_haptic.h | 65 + device_haptic_tsp4000_pattern.h | 125 ++ device_path.h | 42 + devices/CMakeLists.txt | 12 + devices/haptic.c | 63 + devices/jack_35pi.c | 83 + devices/jack_microusb.c | 134 ++ devices/led.c | 68 + devices/mmc.c | 233 +++ devices/power_supply_battery.c | 48 + devices/power_supply_pmic.c | 49 + devices/uart.c | 96 + devices/video.c | 180 ++ devlog.h | 177 ++ devman | 35 + devman.h | 474 +++++ devman.pc.in | 13 + devman_haptic.h | 391 +++++ devman_haptic.pc.in | 13 + devman_haptic_ext.h | 1303 ++++++++++++++ devman_haptic_ext_core.h | 377 ++++ devman_internal.c | 126 ++ devman_internal.h | 32 + display_wd.c | 113 ++ generic_haptic.c | 71 + generic_jack.c | 69 + generic_led.c | 57 + generic_powersupply.c | 48 + generic_video.c | 91 + if_generic.c | 89 + if_legacy.c | 296 ++++ image/SLP_devman_PG_architecture.png | Bin 0 -> 59818 bytes image/SLP_devman_PG_haptic_architecture.png | Bin 0 -> 21787 bytes packaging/devman.spec | 86 + packaging/devman.yaml | 48 + udev-files/91-devman.rules.in | 3 + 85 files changed, 9783 insertions(+) create mode 100644 AUTHORS create mode 100644 CMakeLists.txt create mode 100644 LICENSE create mode 100644 SLP_devman_PG.h create mode 100755 TC/build.sh create mode 100755 TC/execute.sh create mode 100755 TC/tet_code create mode 100755 TC/tet_scen create mode 100755 TC/tetbuild.cfg create mode 100755 TC/tetclean.cfg create mode 100755 TC/tetexec.cfg create mode 100644 TC/unit/Makefile create mode 100755 TC/unit/tc_gen.sh create mode 100644 TC/unit/tslist create mode 100644 TC/unit/utc_MODULE_API_func.c.in create mode 100644 TC/unit/utc_SystemFW_device_get_battery_pct_func.c create mode 100644 TC/unit/utc_SystemFW_device_get_display_brt_func.c create mode 100644 TC/unit/utc_SystemFW_device_get_display_gamma_func.c create mode 100644 TC/unit/utc_SystemFW_device_get_max_brt_func.c create mode 100644 TC/unit/utc_SystemFW_device_get_property_func.c create mode 100644 TC/unit/utc_SystemFW_device_haptic_close_func.c create mode 100644 TC/unit/utc_SystemFW_device_haptic_get_file_duration_func.c create mode 100644 TC/unit/utc_SystemFW_device_haptic_get_pattern_duration_func.c create mode 100644 TC/unit/utc_SystemFW_device_haptic_open_func.c create mode 100644 TC/unit/utc_SystemFW_device_haptic_play_file_func.c create mode 100644 TC/unit/utc_SystemFW_device_haptic_play_monotone_func.c create mode 100644 TC/unit/utc_SystemFW_device_haptic_play_pattern_func.c create mode 100644 TC/unit/utc_SystemFW_device_haptic_stop_play_func.c create mode 100644 TC/unit/utc_SystemFW_device_is_battery_full_func.c create mode 100644 TC/unit/utc_SystemFW_device_release_brt_ctrl_func.c create mode 100644 TC/unit/utc_SystemFW_device_release_gamma_ctrl_func.c create mode 100644 TC/unit/utc_SystemFW_device_set_display_brt_func.c create mode 100644 TC/unit/utc_SystemFW_device_set_display_gamma_func.c create mode 100644 TC/unit/utc_SystemFW_device_set_property_func.c create mode 100644 debian/changelog create mode 100644 debian/compat create mode 100644 debian/control create mode 100644 debian/dirs create mode 100644 debian/docs create mode 100644 debian/libdevman-0.install.in create mode 100755 debian/libdevman-0.postinst.in create mode 100755 debian/libdevman-0.postrm.in create mode 100644 debian/libdevman-dev.install.in create mode 100644 debian/libdevman-haptic-dev.install.in create mode 100755 debian/rules create mode 100644 device_engine.c create mode 100644 device_engine.h create mode 100644 device_generic.h create mode 100644 device_haptic.c create mode 100644 device_haptic.h create mode 100644 device_haptic_tsp4000_pattern.h create mode 100644 device_path.h create mode 100644 devices/CMakeLists.txt create mode 100644 devices/haptic.c create mode 100644 devices/jack_35pi.c create mode 100644 devices/jack_microusb.c create mode 100644 devices/led.c create mode 100644 devices/mmc.c create mode 100644 devices/power_supply_battery.c create mode 100644 devices/power_supply_pmic.c create mode 100644 devices/uart.c create mode 100644 devices/video.c create mode 100644 devlog.h create mode 100755 devman create mode 100644 devman.h create mode 100644 devman.pc.in create mode 100644 devman_haptic.h create mode 100644 devman_haptic.pc.in create mode 100644 devman_haptic_ext.h create mode 100644 devman_haptic_ext_core.h create mode 100644 devman_internal.c create mode 100644 devman_internal.h create mode 100644 display_wd.c create mode 100644 generic_haptic.c create mode 100644 generic_jack.c create mode 100644 generic_led.c create mode 100644 generic_powersupply.c create mode 100644 generic_video.c create mode 100644 if_generic.c create mode 100644 if_legacy.c create mode 100755 image/SLP_devman_PG_architecture.png create mode 100755 image/SLP_devman_PG_haptic_architecture.png create mode 100644 packaging/devman.spec create mode 100644 packaging/devman.yaml create mode 100755 udev-files/91-devman.rules.in diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 0000000..67e6bd9 --- /dev/null +++ b/AUTHORS @@ -0,0 +1,2 @@ +Jinkun Jang +DongGi Jang diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..45da93d --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,88 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 2.6) +PROJECT(devman C) + +INCLUDE(FindPkgConfig) +pkg_check_modules(rpkgs REQUIRED + vconf + sysman + dlog + heynoti) +ADD_DEFINITIONS(${rpkgs_CFLAGS}) + +SET(CMAKE_ALLOW_LOOSE_LOOP_CONSTRAINTS true) + +SET(SRCS + device_engine.c + device_haptic.c + generic_haptic.c + generic_jack.c + generic_powersupply.c + generic_video.c + generic_led.c + if_legacy.c + if_generic.c + devman_internal.c) + +SET(HEADERS + devman.h + devman_haptic.h + devman_haptic_ext.h + devman_haptic_ext_core.h + SLP_devman_PG.h) + +INCLUDE(devices/CMakeLists.txt) + +SET(PREFIX ${CMAKE_INSTALL_PREFIX}) +SET(EXEC_PREFIX "\${prefix}") +SET(LIBDIR "\${prefix}/lib") +SET(INCLUDEDIR "\${prefix}/include/${PROJECT_NAME}") +SET(DATADIR ${CMAKE_DATADIR}) +SET(VERSION 0.1) + +SET(UDEV_RULES_PATH ${CMAKE_DEVMAN_RSRC_PREFIX}/udev-rules) +SET(UDEV_RULES udev-files/91-devman.rules) +SET(RC_LOCAL_SCRIPT devman) + +INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}) + +SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fvisibility=hidden") +SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -g") + +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}") + +ADD_DEFINITIONS("-DPREFIX=\"${PREFIX}\"") +ADD_DEFINITIONS("-DFACTORYFS=\"$ENV{FACTORYFS}\"") +ADD_DEFINITIONS("-DENABLE_DLOG_OUT -DSLP_DEBUG") + +ADD_LIBRARY(${PROJECT_NAME} SHARED ${SRCS} ${TARGET_SRCS}) + +TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${rpkgs_LDFLAGS} "-ldl") +SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES SOVERSION ${VERSION}) + +ADD_EXECUTABLE(display_wd display_wd.c) +TARGET_LINK_LIBRARIES(display_wd ${pkgs_LDFLAGS} ${PROJECT_NAME}) +INSTALL(TARGETS display_wd DESTINATION bin) + +CONFIGURE_FILE(${PROJECT_NAME}.pc.in ${PROJECT_NAME}.pc @ONLY) +CONFIGURE_FILE(devman_haptic.pc.in devman_haptic.pc @ONLY) +CONFIGURE_FILE(${UDEV_RULES}.in ${UDEV_RULES} @ONLY) + +INSTALL(TARGETS ${PROJECT_NAME} DESTINATION lib COMPONENT RuntimeLibraries) +INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc DESTINATION lib/pkgconfig) +INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}_haptic.pc DESTINATION lib/pkgconfig) + +FOREACH(hfile ${HEADERS}) + INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/${hfile} DESTINATION include/${PROJECT_NAME}) +ENDFOREACH(hfile) + +FOREACH(rfile ${UDEV_RULES}) + INSTALL(FILES ${rfile} DESTINATION ${UDEV_RULES_PATH}) +ENDFOREACH(rfile) + +FOREACH(sfile ${PDP_FILES}) + INSTALL(FILES ${sfile} DESTINATION sbin) +ENDFOREACH(sfile) + +INSTALL(FILES ${UDEV_SMDEL} DESTINATION bin) +INSTALL(FILES ${UDEV_USB} DESTINATION sbin) +INSTALL(PROGRAMS ${RC_LOCAL_SCRIPT} DESTINATION /etc/rc.d/init.d) diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..9c13a9b --- /dev/null +++ b/LICENSE @@ -0,0 +1,204 @@ +Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + diff --git a/SLP_devman_PG.h b/SLP_devman_PG.h new file mode 100644 index 0000000..0c92c17 --- /dev/null +++ b/SLP_devman_PG.h @@ -0,0 +1,353 @@ +/* + * devman + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: DongGi Jang + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * +*/ + + +/** + * + * @ingroup SLP_PG + * @defgroup SLP_PG_DEVMAN Device Manager + * @{ + +

Introduction

+ +

Purpose

+The purpose of this document is to describe how applications can use Device Manager APIs. This document gives programming guidelines to application engineers. + +

Scope

+The scope of this document is limited to Device Manager API usage. + +
+

Device Manager Library Overview

+

General Device Manager

+Device Manager library is provided to control the device and to get data about several devices. You can get the data about battery, charger, display and so on.
+Devman library uses sysfs for interfaces with device drivers and kernel. sysfs is a virtual file system provided by Linux 2.6 or above. Please refer to the web site, +http://www.kernel.org/pub/linux/kernel/people/mochel/doc/papers/ols-2005/mochel.pdf for more information about sysfs. +The following figure shows the basic architecture of devman library + +

Device Manager Architecture

+@image html SLP_devman_PG_architecture.png +
+

Haptic Device Manager

+

Haptic Vibration Functional Level Architecture

+@image html SLP_devman_PG_haptic_architecture.png + +The client side is available in the form of a shared library to all the processes, whereas the server is a daemon. +As shown in the diagram applications/middleware frameworks can have the haptic vibration client library in the process context. +

+The haptic vibration client is available in form of a shared library. This library has APIs which support various features. +These features are playing a rhythmical vibration pattern, playing a monotonous vibration pattern, etc. +Applications can call these APIs to give vibration feedback on any event. This could also be used to indicate any events or changes of a state to the user. +

+The server interacts with the device driver interfaces and generates vibration feedback. +

+

Haptic Vibration Features

+Haptic client features +-# Available in shared library form.
+-# Provides set of APIs to play haptic vibration patterns.
+-# Provide unique access control mechanism through client server architecture.
+-# Provision to play rhythmical vibration patterns.
+-# Provides functionality for application to play a different vibration pattern for a different event.
+-# Provides support for user defined duration for monotone playing or iteration for pattern playing.
+-# Provides immediate stop control over the vibrations played.

+ +Haptic server features +-# The actual implementation of the functionality supported by haptic-vibration library has been implemented through haptic-server.
+-# Haptic-server processes the vibration pattern's play/stop requests sent by application through the haptic client library.
+-# There is an internal database maintained for different patterns and their specification.
+-# When application requests a particular pattern, haptic server checks this database for the specification of that pattern.
+-# After getting data from database, server sends these specific details to device driver which plays the pattern.
+-# Server can maintain multiple requests at a time on a priority basis.

+ +

Device Manager Funtions

+ +

General Device Manager APIs

+API : device_get_battery_pct
+Parameter : void
+Return : int
+Functionality : This API is used to get the remaining battery percentage. On success, integer value(0~100) that indicate remaining battery percentage is returned. +Or a negative value (-1) is returned on failure. +

+API : device_is_battery_full
+Parameter : void
+Return : int
+Functionality : This API is used to get the fully charged status of battery. On fully charged, the integer value (1) is returned, +(0) is returned if battery is not fully charged, a negative value (-1) is returned on failure. +

+API : device_get_display_brt +
Parameter In : display_num_t num +
Return : int +
Functionality : This API is used to get the current brightness of the display from sysfs. +The function returns the current brightness value on success and a negative value (-1) on failure. +

+Enumerate values: +@code +// Display number +typedef enum { + DEV_DISPLAY_0, + DEV_DISPLAY_1, + DEV_MAIN_DISPLAY = DEV_DISPLAY_0, +} display_num_t; +@endcode + +API : device_set_display_brt +
Parameter In : display_num_t num +
Parameter In : int val +
Return : int +
Functionality : This API is used to set the current brightness of the display using sysfs. +The parameter val should be set as a brightnesss value of your target. +The function returns the current brightness value on success and a negative value (-1) on failure. +

+API : device_get_display_gamma +
Parameter In : display_num_t num +
Return : int +
Functionality : This API is used to get the current gamma value of the display from sysfs. +The function returns the current brightness value on success and a negative value (-1) on failure. +

+API : device_set_display_brt +
Parameter In : display_num_t num +
Parameter In : int val +
Return : int +
Functionality : This API is used to set the current brightness of the display using sysfs. +The parameter val should be set as a brightnesss value of your target. +The function returns the current brightness value on success and a negative value (-1) on failure. +

+API : device_get_display_gamma +
Parameter In : display_num_t num +
Return : int +
Functionality : This API is used to get the current gamma value of the display from sysfs. +The function returns the current brightness value on success and a negative value (-1) on failure. +Enumerate values: +@code +// LCD gamma values +typedef enum { + LCD_GAMMA_22 = 1, // 8500K , 2.2 GAMMA + LCD_GAMMA_19 = 2, // 8500K , 1.9 GAMMA + LCD_GAMMA_17 = 3, // 8500K , 1.7 GAMMA + LCD_GAMMA_NORMAL = LCD_GAMMA_22, // Normal screen + LCD_GAMMA_PLAY_RECORD = LCD_GAMMA_19, // Playing or recording cam + LCD_GAMMA_PREVIEW = LCD_GAMMA_17, // Preview + LCD_GAMMA_MOVIE = LCD_GAMMA_19, // Movie + LCD_GAMMA_CAMERA = 11, // Camera +} display_gamma_t; +@endcode + +API : device_power_suspend +
Parameter : void +
Return : int +
Functionality : This API is used to make the phone go to a suspend (sleep) state. +The suspend state consumes little battery power. If the caller process does not have the permission which is root, it returns failure. +The function returns 0 on success and a negative value (-1) on failure. +

+API : device_get_property +
Parameter In : devtype_t devtype +
Parameter In : int property +
Parameter Out : int *value +
Return : int +
Functionality :This generic API is used to get the property values of supported devices. +If the caller process does not have permission, it returns failure. +The function returns 0 on success and a negative value (-1) on failure. +

+API : device_set_property +
Parameter In : devtype_t devtype +
Parameter In : int property +
Parameter In : int value +
Return : int +
Functionality :This generic API is used to set the property values of supported devices. +If the caller process does not have permission, it returns failure. +The function returns 0 on success and a negative value (-1) on failure. + +

Haptic Device Manager APIs

+API : device_haptic_open +
Parameter In : haptic_dev_idx dev_idx , unsigned int mode +
Return : int +
Functionality : This API opens a Haptic-vibration device. On success it returns a dev_handle value. +In case of failure it returns a negative value. If the device is already open it returns (-1).
+The first in parameter dev_idx should be from a predefined haptic-device-index which is available in the typedef enum haptic_dev_idx. +The DEV_IDX_0 means first haptic-device-index of target , the DEV_IDX_1 means second haptic-device-index of target and the DEV_IDX_ALL means both of them. +The availability of the dev_idx value is dependent on the real target. Normally, set a DEV_IDX_0 value to the first haptic-device.
+The second in parameter mode is reserved for future so just set a 0 value
+Note: The device_haptic_open() must be called before all other haptic APIs are called. +The device_haptic_open() should have a matching call to device_haptic_close(). +Applications call the device_haptic_open() only once if possible during application startup and call the device_haptic_close() during application shutdown. + +Enumerate values: +@code +//Haptic_dev_idx ; +typedef enum haptic_dev_idx_t { + DEV_IDX_0 = 0x01, + DEV_IDX_1 = 0x02, + DEV_IDX_ALL = 0x04, +}; +@endcode + +API : device_haptic_close +
Parameter In : int dev_handle +
Parameter Return : int +
Functionality : This API closes a Haptic-vibration device. On success it returns a zero value. +In case of failure it returns a negative value. If the device is already closed it returns (-1).
+The first in parameter dev_handle should be from the return value of device_haptic_open(). +

+API : device_haptic_play_pattern +
Parameter In : int dev_handle , int pattern , int iteration , int feedback_level +
Parameter Return : int +
Functionality : This API plays a predefined rhythmic haptic-vibration pattern.
+The first in parameter dev_handle should be from the return value of device_haptic_open().
+The second in parameter pattern should be from a predefined pattern list which is available in an enumeration (effectvibe_pattern_list). +These patterns are rhythmic vibration patterns.
+The third in parameter iteration sets the number of iterations to be played. This should be less than the maximum iteration range set for the device (currently its 255).
+The fourth in parameter is the vibration feedback intensity level. This level is already predefined by enumeration type value from HAPTIC _FEEDBACK_LEVEL_1 +to HAPTIC _FEEDBACK_LEVEL_5. If you want to use the value selected by the user in the Setting application menu, just set -1 value.
+On success it returns a zero value. In case of failure it returns a negative value.
+Note: The actual behavior of the feedback play pattern and the intensity depends on the target hardware. + +Enumerate values: +@code +//Effectvibe_pattern_list +enum effectvibe_pattern_list { + EFFCTVIBE_TOUCH = 0, + EFFCTVIBE_HW_TOUCH, + EFFCTVIBE_NOTIFICATION, + EFFCTVIBE_INCOMING_CALL01, + EFFCTVIBE_INCOMING_CALL02, + EFFCTVIBE_INCOMONG_CALL03, + EFFCTVIBE_ALERTS_CALL, + EFFCTVIBE_OPERATION, + EFFCTVIBE_SILENT_MODE, + EFFCTVIBE_PATTERN_END +}; + +//Feedback Level ; +enum { + HAPTIC_FEEDBACK_LEVEL_AUTO = -1, + HAPTIC_FEEDBACK_LEVEL_1 = 1, + HAPTIC_FEEDBACK_LEVEL_2 = 2, + HAPTIC_FEEDBACK_LEVEL_3 = 3, + HAPTIC_FEEDBACK_LEVEL_4 = 4, + HAPTIC_FEEDBACK_LEVEL_5 = 5, +}; + +//definition for infinite iteration ; +#define HAPTIC_INFINITE_ITERATION 256 +@endcode + +API : device_haptic_play_file +
Parameter In : int dev_handle , const char *file_name , int iteration , int feedback_level +
Parameter Return : int +
Functionality :This API plays a predefined rhythmic haptic-vibration pattern file (only supports .ivt type file, Immersion VibeTonz).
+The first in parameter dev_handle should be from the return value of device_haptic_open().
+The second in parameter file_name sets rhythmic vibration pattern file with path. It only supports .ivt type pattern file.
+The third in parameter iteration sets the number of iterations to be played. This should be less than the maximum iteration range set for the device (currently its 255). +If you want to play indefinitely, use HAPTIC_INFINITE_ITERATION defined value. But it depends on the target hardware.
+The fourth in parameter is the vibration feedback intensity level. This level is already predefined by enumeration type value from HAPTIC _FEEDBACK_LEVEL_1 +to HAPTIC _FEEDBACK_LEVEL_5. If you want to use the value selected by the user in the Setting application menu, just set HAPTIC_FEEDBACK_LEVEL_AUTO value. +(But the application must have a main loop to use the HAPTIC_FEEDBACK_LEVEL_AUTO value )
+On success it returns a zero value. In case of failure it returns a negative value.
+Note: The actual behavior of the feedback play pattern and the intensity depends on the target hardware. +

+API : device_haptic_play_monotone +
Parameter In : int dev_handle , int duration +
Parameter Return : int +
Functionality :This API plays a monotonous haptic-vibration pattern with a constant intensity. +In this monotone play, the intensity used is the value that the user has selected in the Setting application menu.
+The first in parameter dev_handle should be from the return value of device_haptic_open().
+The second in parameter duration defines the length of time this vibration should be played. This duration is in milliseconds.
+On success it returns a zero value. In case of failure it returns a negative value.
+Note: The actual behavior of the feedback played and the intensity depends on the target hardware. +

+API : device_haptic_stop_play +
Parameter In : int dev_handle +
Parameter Return : int +
Functionality : This API stops the current vibration being played.
+The first in parameter dev_handle should be from the return value of device_haptic_open().
+On success it returns a zero value. In case of failure it returns a negative value. +

+API : device_haptic_get_pattern_duration +
Parameter In : int dev_handle , int pattern +
Parameter Out : int *duration +
Parameter Return : int +
Functionality :This API gets a duration time value from a predefined rhythmic vibration pattern.
+The first in parameter dev_handle should be from the return value of device_haptic_open().
+The second in parameter pattern should be from a predefined pattern list which is available in an enumeration (effectvibe_pattern_list).
+The application can get a duration time value from the third out parameter duration when this API succeeds. The unit of duration is ms (millisecond)
+On success it returns a zero value. In case of failure it returns a negative value.
+Note: The actual behavior of the feedback played and the intensity depends on the target hardware. +

+API : device_haptic_get_file_duration +
Parameter In : int dev_handle , const char *file_name +
Parameter Out : int *duration +
Parameter Return : int +
Functionality :This API gets a duration time value from a predefined rhythmic vibration pattern file (only supports .ivt type file).
+The first in parameter dev_handle should be from the return value of device_haptic_open().
+The second in parameter file_name sets rhythmic vibration pattern file with path. It only supports .ivt type pattern file.
+The application can get a duration time value from the third out parameter duration when this API succeeds. The unit of duration is ms (millisecond)
+On success it returns a zero value. In case of failure it returns a negative value.
+Note:The actual behavior of the feedback played and the intensity depends on the target hardware.
+ +
Sample Code +@code +#include +#include +#define HAPTIC_TEST_ITERATION 10 + +int main() +{ + int ret_val=0; + int dev_handle; + + printf("\n Haptic vibration test : Start of the program \n"); + + //Open the haptic device + dev_handle = device_haptic_open(DEV_IDX_0,0); + if(dev_handle < 0) + return -1; + + //Play a rhythmic pattern + ret_val = device_haptic_play_pattern(dev_handle, EFFCTVIBE_NOTIFICATION, + HAPTIC_TEST_ITERATION , HAPTIC_FEEDBACK_LEVEL_3); + if(ret_val !=0) + return -1; + + //Play a monotone pattern for 1s == 1000ms + ret_val = device_haptic_play_monotone(dev_handle, 1000); + if(ret_val !=0) + return -1; + + //Demo for a stop pattern API, playing a monotone for 10s + ret_val = device_haptic_play_monotone(dev_handle, 10000); + if(ret_val !=0) + return -1; + + sleep(1); + + //Stop the pattern immediately + ret_val = device_haptic_stop_play(dev_handle); + if(ret_val !=0) + return -1; + + //Close the device + ret_val = device_haptic_close(dev_handle); + if(ret_val !=0) + return -1; +} +@endcode + + @} +**/ diff --git a/TC/build.sh b/TC/build.sh new file mode 100755 index 0000000..98ebeff --- /dev/null +++ b/TC/build.sh @@ -0,0 +1,20 @@ +#!/bin/sh + +export TET_INSTALL_PATH=/scratchbox/tetware # local tetware path +export TET_TARGET_PATH=$TET_INSTALL_PATH/tetware-target +export PATH=$TET_TARGET_PATH/bin:$PATH +export LD_LIBRARY_PATH=$TET_TARGET_PATH/lib/tet3:$LD_LIBRARY_PATH +export TET_ROOT=$TET_TARGET_PATH + +export TET_SUITE_ROOT=`pwd` +FILE_NAME_EXTENSION=`date +%s` + +RESULT_DIR=results +HTML_RESULT=$RESULT_DIR/build-tar-result-$FILE_NAME_EXTENSION.html +JOURNAL_RESULT=$RESULT_DIR/build-tar-result-$FILE_NAME_EXTENSION.journal + +mkdir -p $RESULT_DIR + +tcc -c -p ./ +tcc -b -j $JOURNAL_RESULT -p ./ +grw -c 3 -f chtml -o $HTML_RESULT $JOURNAL_RESULT diff --git a/TC/execute.sh b/TC/execute.sh new file mode 100755 index 0000000..6720da0 --- /dev/null +++ b/TC/execute.sh @@ -0,0 +1,19 @@ +#!/bin/sh +export TET_INSTALL_PATH=/mnt/nfs/tetware +export TET_TARGET_PATH=$TET_INSTALL_PATH/tetware-target +export PATH=$TET_TARGET_PATH/bin:$PATH +export LD_LIBRARY_PATH=$TET_TARGET_PATH/lib/tet3:$LD_LIBRARY_PATH + +export TET_ROOT=$TET_TARGET_PATH + +export TET_SUITE_ROOT=`pwd` +FILE_NAME_EXTENSION=`date +%s` + +RESULT_DIR=results +HTML_RESULT=$RESULT_DIR/exec-tar-result-$FILE_NAME_EXTENSION.html +JOURNAL_RESULT=$RESULT_DIR/exec-tar-result-$FILE_NAME_EXTENSION.journal + +mkdir -p $RESULT_DIR + +tcc -e -j $JOURNAL_RESULT -p ./ +grw -c 3 -f chtml -o $HTML_RESULT $JOURNAL_RESULT diff --git a/TC/tet_code b/TC/tet_code new file mode 100755 index 0000000..a2cf6c1 --- /dev/null +++ b/TC/tet_code @@ -0,0 +1,12 @@ +# TET reserved codes +0 "PASS" +1 "FAIL" +2 "UNRESOLVED" +3 "NOTINUSE" +4 "UNSUPPORTED" +5 "UNTESTED" +6 "UNINITIATED" +7 "NORESULT" + +# Test suite additional codes +33 "INSPECT" diff --git a/TC/tet_scen b/TC/tet_scen new file mode 100755 index 0000000..43cbc9b --- /dev/null +++ b/TC/tet_scen @@ -0,0 +1,7 @@ +all + ^TEST +##### Scenarios for TEST ##### + +# Test scenario +TEST + :include:/unit/tslist diff --git a/TC/tetbuild.cfg b/TC/tetbuild.cfg new file mode 100755 index 0000000..6192c78 --- /dev/null +++ b/TC/tetbuild.cfg @@ -0,0 +1,3 @@ +TET_OUTPUT_CAPTURE=False +TET_BUILD_TOOL=make +TET_PASS_TC_NAME=True diff --git a/TC/tetclean.cfg b/TC/tetclean.cfg new file mode 100755 index 0000000..c66eda4 --- /dev/null +++ b/TC/tetclean.cfg @@ -0,0 +1,2 @@ +TET_OUTPUT_CAPTURE=False +TET_CLEAN_TOOL=make clean diff --git a/TC/tetexec.cfg b/TC/tetexec.cfg new file mode 100755 index 0000000..0d9d39a --- /dev/null +++ b/TC/tetexec.cfg @@ -0,0 +1 @@ +TET_OUTPUT_CAPTURE=False diff --git a/TC/unit/Makefile b/TC/unit/Makefile new file mode 100644 index 0000000..7717ebf --- /dev/null +++ b/TC/unit/Makefile @@ -0,0 +1,42 @@ +CC ?= gcc + +TARGETS = utc_SystemFW_device_get_battery_pct_func \ + utc_SystemFW_device_get_display_brt_func \ + utc_SystemFW_device_get_display_gamma_func \ + utc_SystemFW_device_get_max_brt_func \ + utc_SystemFW_device_get_property_func \ + utc_SystemFW_device_haptic_open_func \ + utc_SystemFW_device_haptic_close_func \ + utc_SystemFW_device_haptic_get_file_duration_func \ + utc_SystemFW_device_haptic_get_pattern_duration_func \ + utc_SystemFW_device_haptic_play_file_func \ + utc_SystemFW_device_haptic_play_monotone_func \ + utc_SystemFW_device_haptic_play_pattern_func \ + utc_SystemFW_device_haptic_stop_play_func \ + utc_SystemFW_device_is_battery_full_func \ + utc_SystemFW_device_release_brt_ctrl_func \ + utc_SystemFW_device_release_gamma_ctrl_func \ + utc_SystemFW_device_set_display_brt_func \ + utc_SystemFW_device_set_display_gamma_func \ + utc_SystemFW_device_set_property_func \ + + + +PKGS = devman + +LDFLAGS = `pkg-config --libs $(PKGS)` +LDFLAGS += $(TET_ROOT)/lib/tet3/tcm_s.o +LDFLAGS += -L$(TET_ROOT)/lib/tet3 -ltcm_s +LDFLAGS += -L$(TET_ROOT)/lib/tet3 -lapi_s + +CFLAGS = -I. `pkg-config --cflags $(PKGS)` +CFLAGS += -I$(TET_ROOT)/inc/tet3 +CFLAGS += -Wall + +all: $(TARGETS) + +$(TARGETS): %: %.c + $(CC) -o $@ $< $(CFLAGS) $(LDFLAGS) + +clean: + rm -f $(TARGETS) diff --git a/TC/unit/tc_gen.sh b/TC/unit/tc_gen.sh new file mode 100755 index 0000000..54f482d --- /dev/null +++ b/TC/unit/tc_gen.sh @@ -0,0 +1,28 @@ +#!/bin/sh + +TMPSTR=$0 +SCRIPT=${TMPSTR##*/} + +if [ $# -lt 2 ]; then + echo "Usage) $SCRIPT module_name api_name" + exit 1 +fi + +MODULE=$1 +API=$2 +TEMPLATE=utc_MODULE_API_func.c.in +TESTCASE=utc_${MODULE}_${API}_func + +sed -e ' + s^@API@^'"$API"'^g + s^@MODULE@^'"$MODULE"'^g + ' $TEMPLATE > $TESTCASE.c + +if [ ! -e "$TESTCASE.c" ]; then + echo "Failed" + exit 1 +fi +echo "Testcase file is $TESTCASE.c" +echo "Done" +echo "please put \"$TESTCASE\" as Target in Makefile" +echo "please put \"/unit/$TESTCASE\" in tslist" diff --git a/TC/unit/tslist b/TC/unit/tslist new file mode 100644 index 0000000..eedb7cc --- /dev/null +++ b/TC/unit/tslist @@ -0,0 +1,19 @@ +/unit/utc_SystemFW_device_get_battery_pct_func +/unit/utc_SystemFW_device_get_display_brt_func +/unit/utc_SystemFW_device_get_display_gamma_func +/unit/utc_SystemFW_device_get_max_brt_func +/unit/utc_SystemFW_device_get_property_func +/unit/utc_SystemFW_device_haptic_open_func +/unit/utc_SystemFW_device_haptic_close_func +/unit/utc_SystemFW_device_haptic_get_file_duration_func +/unit/utc_SystemFW_device_haptic_get_pattern_duration_func +/unit/utc_SystemFW_device_haptic_play_file_func +/unit/utc_SystemFW_device_haptic_play_monotone_func +/unit/utc_SystemFW_device_haptic_play_pattern_func +/unit/utc_SystemFW_device_haptic_stop_play_func +/unit/utc_SystemFW_device_is_battery_full_func +/unit/utc_SystemFW_device_release_brt_ctrl_func +/unit/utc_SystemFW_device_release_gamma_ctrl_func +/unit/utc_SystemFW_device_set_display_brt_func +/unit/utc_SystemFW_device_set_display_gamma_func +/unit/utc_SystemFW_device_set_property_func diff --git a/TC/unit/utc_MODULE_API_func.c.in b/TC/unit/utc_MODULE_API_func.c.in new file mode 100644 index 0000000..b235fa3 --- /dev/null +++ b/TC/unit/utc_MODULE_API_func.c.in @@ -0,0 +1,64 @@ +#include + +static void startup(void); +static void cleanup(void); + +void (*tet_startup)(void) = startup; +void (*tet_cleanup)(void) = cleanup; + +static void utc_@MODULE@_@API@_func_01(void); +static void utc_@MODULE@_@API@_func_02(void); + +enum { + POSITIVE_TC_IDX = 0x01, + NEGATIVE_TC_IDX, +}; + +struct tet_testlist tet_testlist[] = { + { utc_@MODULE@_@API@_func_01, POSITIVE_TC_IDX }, + { utc_@MODULE@_@API@_func_02, NEGATIVE_TC_IDX }, +}; + +static void startup(void) +{ +} + +static void cleanup(void) +{ +} + +/** + * @brief Positive test case of @API@() + */ +static void utc_@MODULE@_@API@_func_01(void) +{ + int r = 0; + +/* + r = @API@(...); +*/ + if (r) { + tet_infoline("@API@() failed in positive test case"); + tet_result(TET_FAIL); + return; + } + tet_result(TET_PASS); +} + +/** + * @brief Negative test case of ug_init @API@() + */ +static void utc_@MODULE@_@API@_func_02(void) +{ + int r = 0; + +/* + r = @API@(...); +*/ + if (r) { + tet_infoline("@API@() failed in negative test case"); + tet_result(TET_FAIL); + return; + } + tet_result(TET_PASS); +} diff --git a/TC/unit/utc_SystemFW_device_get_battery_pct_func.c b/TC/unit/utc_SystemFW_device_get_battery_pct_func.c new file mode 100644 index 0000000..7ad4398 --- /dev/null +++ b/TC/unit/utc_SystemFW_device_get_battery_pct_func.c @@ -0,0 +1,64 @@ +#include +#include + +static void startup(void); +static void cleanup(void); + +void (*tet_startup)(void) = startup; +void (*tet_cleanup)(void) = cleanup; + +static void utc_SystemFW_device_get_battery_pct_func_01(void); +//static void utc_SystemFW_device_get_battery_pct_func_02(void); + +enum { + POSITIVE_TC_IDX = 0x01, + NEGATIVE_TC_IDX, +}; + +struct tet_testlist tet_testlist[] = { + { utc_SystemFW_device_get_battery_pct_func_01, POSITIVE_TC_IDX }, +// { utc_SystemFW_device_get_battery_pct_func_02, NEGATIVE_TC_IDX }, + { NULL, 0 }, +}; + +static void startup(void) +{ +} + +static void cleanup(void) +{ +} + +/** + * @brief Positive test case of device_get_battery_pct() + */ +static void utc_SystemFW_device_get_battery_pct_func_01(void) +{ + int r = 0; + + r = device_get_battery_pct(); + if (r<0) { + tet_infoline("device_get_battery_pct() failed in positive test case"); + tet_result(TET_FAIL); + return; + } + tet_result(TET_PASS); +} + +/** + * @brief Negative test case of ug_init device_get_battery_pct() + */ +//static void utc_SystemFW_device_get_battery_pct_func_02(void) +//{ +// int r = 0; + + +// r = device_get_battery_pct(); + +// if (r>=0) { +// tet_infoline("device_get_battery_pct() failed in negative test case"); +// tet_result(TET_FAIL); +// return; +// } +// tet_result(TET_PASS); +//} diff --git a/TC/unit/utc_SystemFW_device_get_display_brt_func.c b/TC/unit/utc_SystemFW_device_get_display_brt_func.c new file mode 100644 index 0000000..fae099b --- /dev/null +++ b/TC/unit/utc_SystemFW_device_get_display_brt_func.c @@ -0,0 +1,66 @@ +#include +#include + +static void startup(void); +static void cleanup(void); + +void (*tet_startup)(void) = startup; +void (*tet_cleanup)(void) = cleanup; + +static void utc_SystemFW_device_get_display_brt_func_01(void); +static void utc_SystemFW_device_get_display_brt_func_02(void); + +enum { + POSITIVE_TC_IDX = 0x01, + NEGATIVE_TC_IDX, +}; + +struct tet_testlist tet_testlist[] = { + { utc_SystemFW_device_get_display_brt_func_01, POSITIVE_TC_IDX }, + { utc_SystemFW_device_get_display_brt_func_02, NEGATIVE_TC_IDX }, + { NULL, 0 }, +}; + +static void startup(void) +{ +} + +static void cleanup(void) +{ +} + +/** + * @brief Positive test case of device_get_display_brt() + */ +static void utc_SystemFW_device_get_display_brt_func_01(void) +{ + int r = 0; + display_num_t disp = DEV_DISPLAY_0; + + r = device_get_display_brt(disp); + + if (r<0) { + tet_infoline("device_get_display_brt() failed in positive test case"); + tet_result(TET_FAIL); + return; + } + tet_result(TET_PASS); +} + +/** + * @brief Negative test case of ug_init device_get_display_brt() + */ +static void utc_SystemFW_device_get_display_brt_func_02(void) +{ + int r = 0; + display_num_t disp = -1; + + r = device_get_display_brt(disp); + + if (r>0) { + tet_infoline("device_get_display_brt() failed in negative test case"); + tet_result(TET_FAIL); + return; + } + tet_result(TET_PASS); +} diff --git a/TC/unit/utc_SystemFW_device_get_display_gamma_func.c b/TC/unit/utc_SystemFW_device_get_display_gamma_func.c new file mode 100644 index 0000000..2cad3a6 --- /dev/null +++ b/TC/unit/utc_SystemFW_device_get_display_gamma_func.c @@ -0,0 +1,66 @@ +#include +#include + +static void startup(void); +static void cleanup(void); + +void (*tet_startup)(void) = startup; +void (*tet_cleanup)(void) = cleanup; + +static void utc_SystemFW_device_get_display_gamma_func_01(void); +static void utc_SystemFW_device_get_display_gamma_func_02(void); + +enum { + POSITIVE_TC_IDX = 0x01, + NEGATIVE_TC_IDX, +}; + +struct tet_testlist tet_testlist[] = { + { utc_SystemFW_device_get_display_gamma_func_01, POSITIVE_TC_IDX }, + { utc_SystemFW_device_get_display_gamma_func_02, NEGATIVE_TC_IDX }, + { NULL, 0 }, +}; + +static void startup(void) +{ +} + +static void cleanup(void) +{ +} + +/** + * @brief Positive test case of device_get_display_gamma() + */ +static void utc_SystemFW_device_get_display_gamma_func_01(void) +{ + int r = 0; + display_num_t disp = DEV_DISPLAY_0; + + r = device_get_display_gamma(disp); + + if (r<0) { + tet_infoline("device_get_display_gamma() failed in positive test case"); + tet_result(TET_FAIL); + return; + } + tet_result(TET_PASS); +} + +/** + * @brief Negative test case of ug_init device_get_display_gamma() + */ +static void utc_SystemFW_device_get_display_gamma_func_02(void) +{ + int r = 0; + display_num_t disp = -1; + + r = device_get_display_gamma(disp); + + if (r>=0) { + tet_infoline("device_get_display_gamma() failed in negative test case"); + tet_result(TET_FAIL); + return; + } + tet_result(TET_PASS); +} diff --git a/TC/unit/utc_SystemFW_device_get_max_brt_func.c b/TC/unit/utc_SystemFW_device_get_max_brt_func.c new file mode 100644 index 0000000..ae5837d --- /dev/null +++ b/TC/unit/utc_SystemFW_device_get_max_brt_func.c @@ -0,0 +1,66 @@ +#include +#include + +static void startup(void); +static void cleanup(void); + +void (*tet_startup)(void) = startup; +void (*tet_cleanup)(void) = cleanup; + +static void utc_SystemFW_device_get_max_brt_func_01(void); +static void utc_SystemFW_device_get_max_brt_func_02(void); + +enum { + POSITIVE_TC_IDX = 0x01, + NEGATIVE_TC_IDX, +}; + +struct tet_testlist tet_testlist[] = { + { utc_SystemFW_device_get_max_brt_func_01, POSITIVE_TC_IDX }, + { utc_SystemFW_device_get_max_brt_func_02, NEGATIVE_TC_IDX }, + { NULL, 0 }, +}; + +static void startup(void) +{ +} + +static void cleanup(void) +{ +} + +/** + * @brief Positive test case of device_get_max_brt() + */ +static void utc_SystemFW_device_get_max_brt_func_01(void) +{ + int r = 0; + display_num_t disp = DEV_DISPLAY_0; + + r = device_get_max_brt(disp); + + if (r < 0) { + tet_infoline("device_get_max_brt() failed in positive test case"); + tet_result(TET_FAIL); + return; + } + tet_result(TET_PASS); +} + +/** + * @brief Negative test case of ug_init device_get_max_brt() + */ +static void utc_SystemFW_device_get_max_brt_func_02(void) +{ + int r = -1; + display_num_t disp = -1; + + r = device_get_max_brt(disp); + + if (r > 0) { + tet_infoline("device_get_max_brt() failed in negative test case"); + tet_result(TET_FAIL); + return; + } + tet_result(TET_PASS); +} diff --git a/TC/unit/utc_SystemFW_device_get_property_func.c b/TC/unit/utc_SystemFW_device_get_property_func.c new file mode 100644 index 0000000..596e132 --- /dev/null +++ b/TC/unit/utc_SystemFW_device_get_property_func.c @@ -0,0 +1,69 @@ +#include +#include + +static void startup(void); +static void cleanup(void); + +void (*tet_startup)(void) = startup; +void (*tet_cleanup)(void) = cleanup; + +static void utc_SystemFW_device_get_property_func_01(void); +static void utc_SystemFW_device_get_property_func_02(void); + +enum { + POSITIVE_TC_IDX = 0x01, + NEGATIVE_TC_IDX, +}; + +struct tet_testlist tet_testlist[] = { + { utc_SystemFW_device_get_property_func_01, POSITIVE_TC_IDX }, + { utc_SystemFW_device_get_property_func_02, NEGATIVE_TC_IDX }, + { NULL, 0 }, +}; + +static void startup(void) +{ +} + +static void cleanup(void) +{ +} + +/** + * @brief Positive test case of device_get_property() + */ +static void utc_SystemFW_device_get_property_func_01(void) +{ + int r = 0; + int value = -1; + int property = DISPLAY_PROP_BRIGHTNESS; + devtype_t devtype = DEVTYPE_DISPLAY0; + + r = device_get_property(devtype,property,&value); + + if (r < 0 || value == -1) { + tet_infoline("device_get_property() failed in positive test case"); + tet_result(TET_FAIL); + return; + } + tet_result(TET_PASS); +} + +/** + * @brief Negative test case of ug_init device_get_property() + */ +static void utc_SystemFW_device_get_property_func_02(void) +{ + int value = -1; + int ret_val = 0; + int property = DISPLAY_PROP_BRIGHTNESS; + devtype_t devtype = -1; + + ret_val = device_get_property(devtype,property,&value); + if((ret_val >= 0) && (value!= -1)) { + tet_infoline("device_get_property() failed in negative test case"); + tet_result(TET_FAIL); + return; + } + tet_result(TET_PASS); +} diff --git a/TC/unit/utc_SystemFW_device_haptic_close_func.c b/TC/unit/utc_SystemFW_device_haptic_close_func.c new file mode 100644 index 0000000..6f2e243 --- /dev/null +++ b/TC/unit/utc_SystemFW_device_haptic_close_func.c @@ -0,0 +1,78 @@ +#include +#include +#include + +static void startup(void); +static void cleanup(void); + +void (*tet_startup)(void) = startup; +void (*tet_cleanup)(void) = cleanup; + +static void utc_SystemFW_device_haptic_close_func_01(void); +static void utc_SystemFW_device_haptic_close_func_02(void); + +enum { + POSITIVE_TC_IDX = 0x01, + NEGATIVE_TC_IDX, +}; + +struct tet_testlist tet_testlist[] = { + { utc_SystemFW_device_haptic_close_func_01, POSITIVE_TC_IDX }, + { utc_SystemFW_device_haptic_close_func_02, NEGATIVE_TC_IDX }, + { NULL, 0 }, +}; + +static void startup(void) +{ +} + +static void cleanup(void) +{ +} + +/** + * @brief Positive test case of device_haptic_close() + */ +static void utc_SystemFW_device_haptic_close_func_01(void) +{ + int r = 0; + unsigned int mode =0; + haptic_dev_idx dev_idx = DEV_IDX_0; + int dev_handle; + + dev_handle = device_haptic_open(dev_idx,mode); + if(dev_handle < 0) + { + tet_infoline("device_haptic_close() failed in positive test case"); + tet_result(TET_FAIL); + return; + } + + r = device_haptic_close(dev_handle); + if(r < 0) + { + tet_infoline("device_haptic_close() failed in positive test case"); + tet_result(TET_FAIL); + return; + } + + tet_result(TET_PASS); +} + +/** + * @brief Negative test case of ug_init device_haptic_close() + */ +static void utc_SystemFW_device_haptic_close_func_02(void) +{ + int r = 0; + int invalid_handle = -1; + + r = device_haptic_close(invalid_handle); + + if (r >= 0) { + tet_infoline("device_haptic_close() failed in negative test case"); + tet_result(TET_FAIL); + return; + } + tet_result(TET_PASS); +} diff --git a/TC/unit/utc_SystemFW_device_haptic_get_file_duration_func.c b/TC/unit/utc_SystemFW_device_haptic_get_file_duration_func.c new file mode 100644 index 0000000..a9089b4 --- /dev/null +++ b/TC/unit/utc_SystemFW_device_haptic_get_file_duration_func.c @@ -0,0 +1,84 @@ +#include +#include +#include + +static void startup(void); +static void cleanup(void); + +void (*tet_startup)(void) = startup; +void (*tet_cleanup)(void) = cleanup; + +static void utc_SystemFW_device_haptic_get_file_duration_func_01(void); +static void utc_SystemFW_device_haptic_get_file_duration_func_02(void); + +enum { + POSITIVE_TC_IDX = 0x01, + NEGATIVE_TC_IDX, +}; + +struct tet_testlist tet_testlist[] = { + { utc_SystemFW_device_haptic_get_file_duration_func_01, POSITIVE_TC_IDX }, + { utc_SystemFW_device_haptic_get_file_duration_func_02, NEGATIVE_TC_IDX }, + { NULL, 0 }, +}; + +static void startup(void) +{ +} + +static void cleanup(void) +{ +} + +/** + * @brief Positive test case of device_haptic_get_file_duration() + */ +static void utc_SystemFW_device_haptic_get_file_duration_func_01(void) +{ + int duration = 0; + int ret_val = 0; + unsigned int mode =0; + char* haptic_file = "/usr/share/immersion/01_Touch/touch_20ms_sharp.ivt"; + haptic_dev_idx dev_idx = DEV_IDX_0; + int dev_handle; + + dev_handle = device_haptic_open(dev_idx,mode); + if(dev_handle < 0) + { + tet_infoline("device_haptic_get_file_duration() failed in positive test case"); + tet_result(TET_FAIL); + return; + } + + ret_val = device_haptic_get_file_duration(dev_handle, haptic_file,&duration); + if((ret_val < 0) || (duration<0)) + { + tet_infoline("device_haptic_get_file_duration() failed in positive test case"); + tet_result(TET_FAIL); + return; + } + + device_haptic_close(dev_handle); + tet_result(TET_PASS); +} + +/** + * @brief Negative test case of ug_init device_haptic_get_file_duration() + */ +static void utc_SystemFW_device_haptic_get_file_duration_func_02(void) +{ + int duration = 0; + int invalid_handle = -1; + int ret_val = 0; + char* haptic_file = "test.ivt"; + + //Get duration from attern file + ret_val = device_haptic_get_file_duration(invalid_handle, haptic_file, &duration); + if(ret_val >= 0) + { + tet_infoline("device_haptic_get_file_duration() failed in negative test case"); + tet_result(TET_FAIL); + return; + } + tet_result(TET_PASS); +} diff --git a/TC/unit/utc_SystemFW_device_haptic_get_pattern_duration_func.c b/TC/unit/utc_SystemFW_device_haptic_get_pattern_duration_func.c new file mode 100644 index 0000000..40a63b2 --- /dev/null +++ b/TC/unit/utc_SystemFW_device_haptic_get_pattern_duration_func.c @@ -0,0 +1,82 @@ +#include +#include +#include +#define HAPTIC_TEST_PATTERN EFFCTVIBE_NOTIFICATION + +static void startup(void); +static void cleanup(void); + +void (*tet_startup)(void) = startup; +void (*tet_cleanup)(void) = cleanup; + +static void utc_SystemFW_device_haptic_get_pattern_duration_func_01(void); +static void utc_SystemFW_device_haptic_get_pattern_duration_func_02(void); + +enum { + POSITIVE_TC_IDX = 0x01, + NEGATIVE_TC_IDX, +}; + +struct tet_testlist tet_testlist[] = { + { utc_SystemFW_device_haptic_get_pattern_duration_func_01, POSITIVE_TC_IDX }, + { utc_SystemFW_device_haptic_get_pattern_duration_func_02, NEGATIVE_TC_IDX }, + { NULL, 0 }, +}; + +static void startup(void) +{ +} + +static void cleanup(void) +{ +} + +/** + * @brief Positive test case of device_haptic_get_pattern_duration() + */ +static void utc_SystemFW_device_haptic_get_pattern_duration_func_01(void) +{ + int duration = 0; + int ret_val = 0; + unsigned int mode =0; + haptic_dev_idx dev_idx = DEV_IDX_0; + int dev_handle; + + dev_handle = device_haptic_open(dev_idx,mode); + if(dev_handle < 0) + { + tet_infoline("device_haptic_get_file_duration() failed in positive test case"); + tet_result(TET_FAIL); + return; + } + + ret_val = device_haptic_get_pattern_duration(dev_handle,HAPTIC_TEST_PATTERN, &duration); + if((ret_val < 0) || (duration < 0)) + { + tet_infoline("device_haptic_get_file_duration() failed in positive test case"); + tet_result(TET_FAIL); + return; + } + + device_haptic_close(dev_handle); + tet_result(TET_PASS); +} + +/** + * @brief Negative test case of ug_init device_haptic_get_pattern_duration() + */ +static void utc_SystemFW_device_haptic_get_pattern_duration_func_02(void) +{ + int ret_val = 0; + int duration = 0; + int invalid_handle = -1; + + ret_val = device_haptic_get_pattern_duration(invalid_handle,HAPTIC_TEST_PATTERN, &duration); + if(ret_val >= 0) + { + tet_infoline("device_haptic_get_file_duration() failed in negative test case"); + tet_result(TET_FAIL); + return; + } + tet_result(TET_PASS); +} diff --git a/TC/unit/utc_SystemFW_device_haptic_open_func.c b/TC/unit/utc_SystemFW_device_haptic_open_func.c new file mode 100644 index 0000000..c8776b1 --- /dev/null +++ b/TC/unit/utc_SystemFW_device_haptic_open_func.c @@ -0,0 +1,71 @@ +#include +#include +#include + +static void startup(void); +static void cleanup(void); + +void (*tet_startup)(void) = startup; +void (*tet_cleanup)(void) = cleanup; + +static void utc_SystemFW_device_haptic_open_func_01(void); +static void utc_SystemFW_device_haptic_open_func_02(void); + +enum { + POSITIVE_TC_IDX = 0x01, + NEGATIVE_TC_IDX, +}; + +struct tet_testlist tet_testlist[] = { + { utc_SystemFW_device_haptic_open_func_01, POSITIVE_TC_IDX }, + { utc_SystemFW_device_haptic_open_func_02, NEGATIVE_TC_IDX }, + { NULL, 0 }, +}; + +static void startup(void) +{ +} + +static void cleanup(void) +{ +} + +/** + * @brief Positive test case of device_haptic_open() + */ +static void utc_SystemFW_device_haptic_open_func_01(void) +{ + int r = 0; + unsigned int mode =0; + haptic_dev_idx dev_idx = DEV_IDX_0; + + r = device_haptic_open(dev_idx,mode); + + if (r < 0) { + tet_infoline("device_haptic_open() failed in positive test case"); + tet_result(TET_FAIL); + return; + } + tet_result(TET_PASS); + device_haptic_close(r); +} + +/** + * @brief Negative test case of ug_init device_haptic_open() + */ +static void utc_SystemFW_device_haptic_open_func_02(void) +{ + int r = 0; + unsigned int mode =0; + haptic_dev_idx dev_idx = 1000; + + r = device_haptic_open(dev_idx,mode); + + if (r >= 0) { + tet_infoline("device_haptic_open() failed in negative test case"); + tet_result(TET_FAIL); + device_haptic_close(r); + return; + } + tet_result(TET_PASS); +} diff --git a/TC/unit/utc_SystemFW_device_haptic_play_file_func.c b/TC/unit/utc_SystemFW_device_haptic_play_file_func.c new file mode 100644 index 0000000..52f5659 --- /dev/null +++ b/TC/unit/utc_SystemFW_device_haptic_play_file_func.c @@ -0,0 +1,82 @@ +#include +#include +#include + +static void startup(void); +static void cleanup(void); + +void (*tet_startup)(void) = startup; +void (*tet_cleanup)(void) = cleanup; + +static void utc_SystemFW_device_haptic_play_file_func_01(void); +static void utc_SystemFW_device_haptic_play_file_func_02(void); + +enum { + POSITIVE_TC_IDX = 0x01, + NEGATIVE_TC_IDX, +}; + +struct tet_testlist tet_testlist[] = { + { utc_SystemFW_device_haptic_play_file_func_01, POSITIVE_TC_IDX }, + { utc_SystemFW_device_haptic_play_file_func_02, NEGATIVE_TC_IDX }, + { NULL, 0 }, +}; + +static void startup(void) +{ +} + +static void cleanup(void) +{ +} + +/** + * @brief Positive test case of device_haptic_play_file() + */ +static void utc_SystemFW_device_haptic_play_file_func_01(void) +{ + int ret_val = 0; + haptic_dev_idx dev_idx = DEV_IDX_0; + unsigned int mode =0; + char* haptic_file = "/usr/share/immersion/01_Touch/touch_20ms_sharp.ivt"; + int dev_handle; + + dev_handle = device_haptic_open(dev_idx,mode); + if(dev_handle < 0) + { + tet_infoline("device_haptic_play_file() failed in positive test case"); + tet_result(TET_FAIL); + return; + } + + ret_val = device_haptic_play_file(dev_handle, haptic_file, 1, 1); + if(ret_val < 0) + { + tet_infoline("device_haptic_play_file() failed in positive test case"); + tet_result(TET_FAIL); + device_haptic_close(dev_handle); + return; + } + + device_haptic_close(dev_handle); + tet_result(TET_PASS); +} + +/** + * @brief Negative test case of ug_init device_haptic_play_file() + */ +static void utc_SystemFW_device_haptic_play_file_func_02(void) +{ + int ret_val = 0; + int invalid_handle = -1; + char* haptic_file = "/usr/share/immersion/01_Touch/touch_20ms_sharp.ivt"; + + ret_val = device_haptic_play_file(invalid_handle, haptic_file, 1, 1); + if(ret_val >= 0) + { + tet_infoline("device_haptic_play_file() failed in negative test case"); + tet_result(TET_FAIL); + return; + } + tet_result(TET_PASS); +} diff --git a/TC/unit/utc_SystemFW_device_haptic_play_monotone_func.c b/TC/unit/utc_SystemFW_device_haptic_play_monotone_func.c new file mode 100644 index 0000000..ded5a33 --- /dev/null +++ b/TC/unit/utc_SystemFW_device_haptic_play_monotone_func.c @@ -0,0 +1,79 @@ +#include +#include +#include + +static void startup(void); +static void cleanup(void); + +void (*tet_startup)(void) = startup; +void (*tet_cleanup)(void) = cleanup; + +static void utc_SystemFW_device_haptic_play_monotone_func_01(void); +static void utc_SystemFW_device_haptic_play_monotone_func_02(void); + +enum { + POSITIVE_TC_IDX = 0x01, + NEGATIVE_TC_IDX, +}; + +struct tet_testlist tet_testlist[] = { + { utc_SystemFW_device_haptic_play_monotone_func_01, POSITIVE_TC_IDX }, + { utc_SystemFW_device_haptic_play_monotone_func_02, NEGATIVE_TC_IDX }, + { NULL, 0 }, +}; + +static void startup(void) +{ +} + +static void cleanup(void) +{ +} + +/** + * @brief Positive test case of device_haptic_play_monotone() + */ +static void utc_SystemFW_device_haptic_play_monotone_func_01(void) +{ + int ret_val = 0; + haptic_dev_idx dev_idx = DEV_IDX_0; + unsigned int mode =0; + int dev_handle; + + dev_handle = device_haptic_open(dev_idx,mode); + if(dev_handle < 0) + { + tet_infoline("device_haptic_play_monotone() failed in positive test case"); + tet_result(TET_FAIL); + return; + } + + ret_val = device_haptic_play_monotone(dev_handle ,1); + if(ret_val < 0) + { + tet_infoline("device_haptic_play_monotone() failed in positive test case"); + tet_result(TET_FAIL); + device_haptic_close(dev_handle); + return; + } + + device_haptic_close(dev_handle); + tet_result(TET_PASS); +} + +/** + * @brief Negative test case of ug_init device_haptic_play_monotone() + */ +static void utc_SystemFW_device_haptic_play_monotone_func_02(void) +{ + int ret_val = 0; + int invalid_handle = -1; + + ret_val = device_haptic_play_monotone(invalid_handle ,1); + if(ret_val >= 0) { + tet_infoline("device_haptic_play_monotone() failed in negative test case"); + tet_result(TET_FAIL); + return; + } + tet_result(TET_PASS); +} diff --git a/TC/unit/utc_SystemFW_device_haptic_play_pattern_func.c b/TC/unit/utc_SystemFW_device_haptic_play_pattern_func.c new file mode 100644 index 0000000..3972a1f --- /dev/null +++ b/TC/unit/utc_SystemFW_device_haptic_play_pattern_func.c @@ -0,0 +1,81 @@ +#include +#include +#include +#define HAPTIC_TEST_PATTERN EFFCTVIBE_NOTIFICATION + +static void startup(void); +static void cleanup(void); + +void (*tet_startup)(void) = startup; +void (*tet_cleanup)(void) = cleanup; + +static void utc_SystemFW_device_haptic_play_pattern_func_01(void); +static void utc_SystemFW_device_haptic_play_pattern_func_02(void); + +enum { + POSITIVE_TC_IDX = 0x01, + NEGATIVE_TC_IDX, +}; + +struct tet_testlist tet_testlist[] = { + { utc_SystemFW_device_haptic_play_pattern_func_01, POSITIVE_TC_IDX }, + { utc_SystemFW_device_haptic_play_pattern_func_02, NEGATIVE_TC_IDX }, + { NULL, 0 }, +}; + +static void startup(void) +{ +} + +static void cleanup(void) +{ +} + +/** + * @brief Positive test case of device_haptic_play_pattern() + */ +static void utc_SystemFW_device_haptic_play_pattern_func_01(void) +{ + int ret_val = 0; + haptic_dev_idx dev_idx = DEV_IDX_0; + unsigned int mode =0; + int dev_handle = 0; + + dev_handle = device_haptic_open(dev_idx,mode); + if(dev_handle < 0) + { + tet_infoline("device_haptic_play_pattern() failed in positive test case"); + tet_result(TET_FAIL); + return; + } + + ret_val = device_haptic_play_pattern(dev_handle, HAPTIC_TEST_PATTERN , 1, 1); + if(ret_val < 0) + { + tet_infoline("device_haptic_play_pattern() failed in positive test case"); + tet_result(TET_FAIL); + device_haptic_close(dev_handle); + return; + } + + device_haptic_close(dev_handle); + tet_result(TET_PASS); +} + +/** + * @brief Negative test case of ug_init device_haptic_play_pattern() + */ +static void utc_SystemFW_device_haptic_play_pattern_func_02(void) +{ + + int ret_val = 0; + int invalid_handle = -1; + + ret_val = device_haptic_play_pattern(invalid_handle, HAPTIC_TEST_PATTERN , 1, 1); + if(ret_val >= 0) { + tet_infoline("device_haptic_play_pattern() failed in negative test case"); + tet_result(TET_FAIL); + return; + } + tet_result(TET_PASS); +} diff --git a/TC/unit/utc_SystemFW_device_haptic_stop_play_func.c b/TC/unit/utc_SystemFW_device_haptic_stop_play_func.c new file mode 100644 index 0000000..aef795c --- /dev/null +++ b/TC/unit/utc_SystemFW_device_haptic_stop_play_func.c @@ -0,0 +1,101 @@ +#include +#include +#include + +static void startup(void); +static void cleanup(void); + +void (*tet_startup)(void) = startup; +void (*tet_cleanup)(void) = cleanup; + +static void utc_SystemFW_device_haptic_stop_play_func_01(void); +static void utc_SystemFW_device_haptic_stop_play_func_02(void); + +enum { + POSITIVE_TC_IDX = 0x01, + NEGATIVE_TC_IDX, +}; + +struct tet_testlist tet_testlist[] = { + { utc_SystemFW_device_haptic_stop_play_func_01, POSITIVE_TC_IDX }, + { utc_SystemFW_device_haptic_stop_play_func_02, NEGATIVE_TC_IDX }, + { NULL, 0 }, +}; + +static void startup(void) +{ +} + +static void cleanup(void) +{ +} + +/** + * @brief Positive test case of device_haptic_stop_play() + */ +static void utc_SystemFW_device_haptic_stop_play_func_01(void) +{ + int ret_val = 0; + haptic_dev_idx dev_idx = DEV_IDX_0; + unsigned int mode =0; + int dev_handle = 0; + + dev_handle = device_haptic_open(dev_idx,mode); + if(dev_handle < 0) + { + tet_infoline("device_haptic_stop_play() failed in positive test case"); + tet_result(TET_FAIL); + return; + } + + ret_val = device_haptic_play_monotone(dev_handle ,100); + if(ret_val < 0) + { + tet_infoline("device_haptic_stop_play() failed in positive test case"); + tet_result(TET_FAIL); + device_haptic_close(dev_handle); + return; + } + + ret_val = device_haptic_stop_play(dev_handle); + if(ret_val < 0) + { + tet_infoline("device_haptic_stop_play() failed in positive test case"); + tet_result(TET_FAIL); + device_haptic_close(dev_handle); + return; + } + + + device_haptic_close(dev_handle); + tet_result(TET_PASS); + int r = 0; + +/* + r = device_haptic_stop_play(...); +*/ + if (r) { + tet_infoline("device_haptic_stop_play() failed in positive test case"); + tet_result(TET_FAIL); + return; + } + tet_result(TET_PASS); +} + +/** + * @brief Negative test case of ug_init device_haptic_stop_play() + */ +static void utc_SystemFW_device_haptic_stop_play_func_02(void) +{ + int r = 0; + + + r = device_haptic_stop_play(-1); + + if (r>=0) { + tet_infoline("device_haptic_stop_play() failed in negative test case"); + tet_result(TET_FAIL); + return; + } + tet_result(TET_PASS); +} diff --git a/TC/unit/utc_SystemFW_device_is_battery_full_func.c b/TC/unit/utc_SystemFW_device_is_battery_full_func.c new file mode 100644 index 0000000..1df689c --- /dev/null +++ b/TC/unit/utc_SystemFW_device_is_battery_full_func.c @@ -0,0 +1,66 @@ +#include +#include + +static void startup(void); +static void cleanup(void); + +void (*tet_startup)(void) = startup; +void (*tet_cleanup)(void) = cleanup; + +static void utc_SystemFW_device_is_battery_full_func_01(void); +//static void utc_SystemFW_device_is_battery_full_func_02(void); + +enum { + POSITIVE_TC_IDX = 0x01, + NEGATIVE_TC_IDX, +}; + +struct tet_testlist tet_testlist[] = { + { utc_SystemFW_device_is_battery_full_func_01, POSITIVE_TC_IDX }, +// { utc_SystemFW_device_is_battery_full_func_02, NEGATIVE_TC_IDX }, + { NULL, 0 }, +}; + +static void startup(void) +{ +} + +static void cleanup(void) +{ +} + +/** + * @brief Positive test case of device_is_battery_full() + */ +static void utc_SystemFW_device_is_battery_full_func_01(void) +{ + + int r = 0; + + + r = device_is_battery_full(); + + if (r<0) { + tet_infoline("device_is_battery_full() failed in positive test case"); + tet_result(TET_FAIL); + return; + } + tet_result(TET_PASS); +} + +/** + * @brief Negative test case of ug_init device_is_battery_full() + */ +//static void utc_SystemFW_device_is_battery_full_func_02(void) +//{ +// int r = 0; +// + // r = device_is_battery_full(); +// +// if (r>=0) { +// tet_infoline("device_is_battery_full() failed in negative test case"); +// tet_result(TET_FAIL); +// return; +// } +// tet_result(TET_PASS); +//} diff --git a/TC/unit/utc_SystemFW_device_release_brt_ctrl_func.c b/TC/unit/utc_SystemFW_device_release_brt_ctrl_func.c new file mode 100644 index 0000000..8eb716e --- /dev/null +++ b/TC/unit/utc_SystemFW_device_release_brt_ctrl_func.c @@ -0,0 +1,73 @@ +#include +#include + +static void startup(void); +static void cleanup(void); + +void (*tet_startup)(void) = startup; +void (*tet_cleanup)(void) = cleanup; + +static void utc_SystemFW_device_release_brt_ctrl_func_01(void); +static void utc_SystemFW_device_release_brt_ctrl_func_02(void); + +enum { + POSITIVE_TC_IDX = 0x01, + NEGATIVE_TC_IDX, +}; + +struct tet_testlist tet_testlist[] = { + { utc_SystemFW_device_release_brt_ctrl_func_01, POSITIVE_TC_IDX }, + { utc_SystemFW_device_release_brt_ctrl_func_02, NEGATIVE_TC_IDX }, + { NULL, 0 }, +}; + +static void startup(void) +{ +} + +static void cleanup(void) +{ +} + +/** + * @brief Positive test case of device_release_brt_ctrl() + */ +static void utc_SystemFW_device_release_brt_ctrl_func_01(void) +{ + int org_brt = 0; + int ret_val = 0; + display_num_t disp = DEV_DISPLAY_0; + + org_brt = device_get_display_brt(disp); + if(org_brt < 0) + org_brt = 7; + + + + ret_val = device_release_brt_ctrl(disp); + if(ret_val < 0) { + tet_infoline("device_release_brt_ctrl() failed in positive test case"); + tet_result(TET_FAIL); + return; + } + tet_result(TET_PASS); +} + +/** + * @brief Negative test case of ug_init device_release_brt_ctrl() + */ +static void utc_SystemFW_device_release_brt_ctrl_func_02(void) +{ + int ret_val = 0; + int org_brt = -1; + + display_num_t disp = -1; + + ret_val = device_release_brt_ctrl(disp); + if(ret_val >=0 ) { + tet_infoline("device_release_brt_ctrl() failed in negative test case"); + tet_result(TET_FAIL); + return; + } + tet_result(TET_PASS); +} diff --git a/TC/unit/utc_SystemFW_device_release_gamma_ctrl_func.c b/TC/unit/utc_SystemFW_device_release_gamma_ctrl_func.c new file mode 100644 index 0000000..9203cf9 --- /dev/null +++ b/TC/unit/utc_SystemFW_device_release_gamma_ctrl_func.c @@ -0,0 +1,67 @@ +#include +#include + +static void startup(void); +static void cleanup(void); + +void (*tet_startup)(void) = startup; +void (*tet_cleanup)(void) = cleanup; + +static void utc_SystemFW_device_release_gamma_ctrl_func_01(void); +static void utc_SystemFW_device_release_gamma_ctrl_func_02(void); + +enum { + POSITIVE_TC_IDX = 0x01, + NEGATIVE_TC_IDX, +}; + +struct tet_testlist tet_testlist[] = { + { utc_SystemFW_device_release_gamma_ctrl_func_01, POSITIVE_TC_IDX }, + { utc_SystemFW_device_release_gamma_ctrl_func_02, NEGATIVE_TC_IDX }, + { NULL, 0 }, +}; + +static void startup(void) +{ +} + +static void cleanup(void) +{ +} + +/** + * @brief Positive test case of device_release_gamma_ctrl() + */ +static void utc_SystemFW_device_release_gamma_ctrl_func_01(void) +{ + int ret_val = 0; + display_num_t disp = DEV_DISPLAY_0; + display_gamma_t org_val = 1; + + ret_val = device_release_gamma_ctrl(disp,org_val); + if(ret_val < 0) { + tet_infoline("device_release_gamma_ctrl() failed in positive test case"); + tet_result(TET_FAIL); + return; + } + tet_result(TET_PASS); +} + +/** + * @brief Negative test case of ug_init device_release_gamma_ctrl() + */ +static void utc_SystemFW_device_release_gamma_ctrl_func_02(void) +{ + int ret_val = 0; + int org_brt = -1; + + display_num_t disp = -1; + + ret_val = device_release_gamma_ctrl(disp,org_brt); + if (ret_val >= 0) { + tet_infoline("device_release_gamma_ctrl() failed in negative test case"); + tet_result(TET_FAIL); + return; + } + tet_result(TET_PASS); +} diff --git a/TC/unit/utc_SystemFW_device_set_display_brt_func.c b/TC/unit/utc_SystemFW_device_set_display_brt_func.c new file mode 100644 index 0000000..f3c9c06 --- /dev/null +++ b/TC/unit/utc_SystemFW_device_set_display_brt_func.c @@ -0,0 +1,65 @@ +#include +#include + +static void startup(void); +static void cleanup(void); + +void (*tet_startup)(void) = startup; +void (*tet_cleanup)(void) = cleanup; + +static void utc_SystemFW_device_set_display_brt_func_01(void); +static void utc_SystemFW_device_set_display_brt_func_02(void); + +enum { + POSITIVE_TC_IDX = 0x01, + NEGATIVE_TC_IDX, +}; + +struct tet_testlist tet_testlist[] = { + { utc_SystemFW_device_set_display_brt_func_01, POSITIVE_TC_IDX }, + { utc_SystemFW_device_set_display_brt_func_02, NEGATIVE_TC_IDX }, + { NULL, 0 }, +}; + +static void startup(void) +{ +} + +static void cleanup(void) +{ +} + +/** + * @brief Positive test case of device_set_display_brt() + */ +static void utc_SystemFW_device_set_display_brt_func_01(void) +{ + int ret_val = 0; + display_num_t disp = DEV_DISPLAY_0; + + ret_val = device_set_display_brt(disp,6); + if(ret_val > 0) { + tet_infoline("device_set_display_brt() failed in positive test case"); + tet_result(TET_FAIL); + return; + } + tet_result(TET_PASS); +} + +/** + * @brief Negative test case of ug_init device_set_display_brt() + */ +static void utc_SystemFW_device_set_display_brt_func_02(void) +{ + int ret_val = 0; + + display_num_t disp = -1; + + ret_val = device_set_display_brt(disp,6); + if(ret_val >= 0) { + tet_infoline("device_set_display_brt() failed in negative test case"); + tet_result(TET_FAIL); + return; + } + tet_result(TET_PASS); +} diff --git a/TC/unit/utc_SystemFW_device_set_display_gamma_func.c b/TC/unit/utc_SystemFW_device_set_display_gamma_func.c new file mode 100644 index 0000000..a703ed8 --- /dev/null +++ b/TC/unit/utc_SystemFW_device_set_display_gamma_func.c @@ -0,0 +1,65 @@ +#include +#include + +static void startup(void); +static void cleanup(void); + +void (*tet_startup)(void) = startup; +void (*tet_cleanup)(void) = cleanup; + +static void utc_SystemFW_device_set_display_gamma_func_01(void); +static void utc_SystemFW_device_set_display_gamma_func_02(void); + +enum { + POSITIVE_TC_IDX = 0x01, + NEGATIVE_TC_IDX, +}; + +struct tet_testlist tet_testlist[] = { + { utc_SystemFW_device_set_display_gamma_func_01, POSITIVE_TC_IDX }, + { utc_SystemFW_device_set_display_gamma_func_02, NEGATIVE_TC_IDX }, + { NULL, 0 }, +}; + +static void startup(void) +{ +} + +static void cleanup(void) +{ +} + +/** + * @brief Positive test case of device_set_display_gamma() + */ +static void utc_SystemFW_device_set_display_gamma_func_01(void) +{ + int r = 0; + display_num_t disp = DEV_DISPLAY_0; + + r = device_set_display_gamma(disp,1); + if (r<0) { + tet_infoline("device_set_display_gamma() failed in positive test case"); + tet_result(TET_FAIL); + return; + } + tet_result(TET_PASS); +} + +/** + * @brief Negative test case of ug_init device_set_display_gamma() + */ +static void utc_SystemFW_device_set_display_gamma_func_02(void) +{ + int r = 0; + display_num_t disp = -1; + + r = device_set_display_gamma(disp,-1); + + if (r>=0) { + tet_infoline("device_set_display_gamma() failed in negative test case"); + tet_result(TET_FAIL); + return; + } + tet_result(TET_PASS); +} diff --git a/TC/unit/utc_SystemFW_device_set_property_func.c b/TC/unit/utc_SystemFW_device_set_property_func.c new file mode 100644 index 0000000..9eb7c44 --- /dev/null +++ b/TC/unit/utc_SystemFW_device_set_property_func.c @@ -0,0 +1,68 @@ +#include +#include + +static void startup(void); +static void cleanup(void); + +void (*tet_startup)(void) = startup; +void (*tet_cleanup)(void) = cleanup; + +static void utc_SystemFW_device_set_property_func_01(void); +static void utc_SystemFW_device_set_property_func_02(void); + +enum { + POSITIVE_TC_IDX = 0x01, + NEGATIVE_TC_IDX, +}; + +struct tet_testlist tet_testlist[] = { + { utc_SystemFW_device_set_property_func_01, POSITIVE_TC_IDX }, + { utc_SystemFW_device_set_property_func_02, NEGATIVE_TC_IDX }, + { NULL, 0 }, +}; + +static void startup(void) +{ +} + +static void cleanup(void) +{ +} + +/** + * @brief Positive test case of device_set_property() + */ +static void utc_SystemFW_device_set_property_func_01(void) +{ + int value = 6; + int ret_val = 0; + int property = DISPLAY_PROP_BRIGHTNESS; + devtype_t devtype = DEVTYPE_DISPLAY0; + + //set brightness to 6 + ret_val = device_set_property(devtype,property,value); + if((ret_val < 0) || (value == -1)) { + tet_infoline("device_set_property() failed in positive test case"); + tet_result(TET_FAIL); + return; + } + tet_result(TET_PASS); +} + +/** + * @brief Negative test case of ug_init device_set_property() + */ +static void utc_SystemFW_device_set_property_func_02(void) +{ + int ret_val = 0; + int property = DISPLAY_PROP_BRIGHTNESS; + devtype_t devtype = -1; + + ret_val = device_set_property(devtype,property,-1); + if(ret_val >= 0) { + tet_infoline("device_set_property() failed in negative test case"); + tet_result(TET_FAIL); + return; + } + tet_result(TET_PASS); +} diff --git a/debian/changelog b/debian/changelog new file mode 100644 index 0000000..868e09c --- /dev/null +++ b/debian/changelog @@ -0,0 +1,23 @@ +devman (0.1.6-77) unstable; urgency=low + + * Fix JIRA Issue + * Git: pkgs/d/devman + * Tag: devman_0.1.6-77 + + -- DongGi Jang Thu, 22 Dec 2011 17:52:51 +0900 + +devman (0.1.6-76) unstable; urgency=low + + * sync version + * Git: pkgs/d/devman + * Tag: devman_0.1.6-76 + + -- Jinkun Jang Thu, 15 Dec 2011 10:50:49 +0900 + +devman (0.0.1-1) unstable; urgency=low + + * initial release + * Git: pkgs/d/devman + * Tag: devman_0.0.1-1 + + -- Jinkun Jang Wed, 07 Dec 2011 12:50:49 +0900 diff --git a/debian/compat b/debian/compat new file mode 100644 index 0000000..7ed6ff8 --- /dev/null +++ b/debian/compat @@ -0,0 +1 @@ +5 diff --git a/debian/control b/debian/control new file mode 100644 index 0000000..f73558c --- /dev/null +++ b/debian/control @@ -0,0 +1,34 @@ +Source: devman +Section: devel +Priority: extra +Maintainer: Jonghoon Han Jinkun Jang DongGi Jang TAESOO JUN +Uploaders: Jinkun Jang +Build-Depends: debhelper (>= 5), libslp-setting-dev, libslp-sysman-dev, dlog-dev, libheynoti-dev +Standards-Version: 0.1.0 + +Package: libdevman-dev +Section: libs +Architecture: any +Depends: libdevman-0 (= ${Source-Version}), libdevman-haptic-dev +XB-Generate-Docs: yes +Description: device manager library for device control + +Package: libdevman-haptic-dev +Section: libs +Architecture: any +Depends: libdevman-0 (= ${Source-Version}), +XB-Generate-Docs: yes +Description: device manager library for device_haptic + +Package: libdevman-0 +Section: libs +Architecture: any +Depends: ${shlibs:Depends}, ${misc:Depends}, +Description: device manager library for device control + +Package: libdevman-dbg +Section: debug +Architecture: any +Depends: ${shlibs:Depends}, ${misc:Depends}, libdevman-0 (= ${Source-Version}) +Description: device manager library for device control (unstripped) + diff --git a/debian/dirs b/debian/dirs new file mode 100644 index 0000000..ca882bb --- /dev/null +++ b/debian/dirs @@ -0,0 +1,2 @@ +usr/bin +usr/sbin diff --git a/debian/docs b/debian/docs new file mode 100644 index 0000000..a0f0008 --- /dev/null +++ b/debian/docs @@ -0,0 +1 @@ +CMakeLists.txt diff --git a/debian/libdevman-0.install.in b/debian/libdevman-0.install.in new file mode 100644 index 0000000..19e8cf6 --- /dev/null +++ b/debian/libdevman-0.install.in @@ -0,0 +1,4 @@ +@PREFIX@/lib/*.so* +@PREFIX@/share/* +@PREFIX@/bin/* +etc/* diff --git a/debian/libdevman-0.postinst.in b/debian/libdevman-0.postinst.in new file mode 100755 index 0000000..02d4738 --- /dev/null +++ b/debian/libdevman-0.postinst.in @@ -0,0 +1,6 @@ +#!/bin/sh +mkdir -p /etc/udev/rules.d +if ! [ -L /etc/udev/rules.d/91-devman.rules ]; then + ln -s @PREFIX@/share/devman/udev-rules/91-devman.rules /etc/udev/rules.d/91-devman.rules +fi + diff --git a/debian/libdevman-0.postrm.in b/debian/libdevman-0.postrm.in new file mode 100755 index 0000000..08f5048 --- /dev/null +++ b/debian/libdevman-0.postrm.in @@ -0,0 +1,2 @@ +#!/bin/sh +rm -f /etc/udev/rules.d/91-X1.rules diff --git a/debian/libdevman-dev.install.in b/debian/libdevman-dev.install.in new file mode 100644 index 0000000..84457c6 --- /dev/null +++ b/debian/libdevman-dev.install.in @@ -0,0 +1,3 @@ +@PREFIX@/include/devman/devman.h +@PREFIX@/include/devman/SLP_devman_PG.h +@PREFIX@/lib/pkgconfig/devman.pc diff --git a/debian/libdevman-haptic-dev.install.in b/debian/libdevman-haptic-dev.install.in new file mode 100644 index 0000000..7dce113 --- /dev/null +++ b/debian/libdevman-haptic-dev.install.in @@ -0,0 +1,2 @@ +@PREFIX@/include/devman/devman_haptic*.h +@PREFIX@/lib/pkgconfig/devman_haptic.pc diff --git a/debian/rules b/debian/rules new file mode 100755 index 0000000..ab5ca11 --- /dev/null +++ b/debian/rules @@ -0,0 +1,134 @@ +#!/usr/bin/make -f +# -*- makefile -*- +# Sample debian/rules that uses debhelper. +# This file was originally written by Joey Hess and Craig Small. +# As a special exception, when this file is copied by dh-make into a +# dh-make output file, you may use that output file without restriction. +# This special exception was added by Craig Small in version 0.37 of dh-make. + +# Uncomment this to turn on verbose mode. +#export DH_VERBOSE=1 + +CFLAGS ?= -Wall -g +CXXFLAGS ?= -Wall -g +LDFLAGS ?= +PREFIX ?= /usr +DATADIR ?= /opt +DEVMAN_RSRCDIR ?= share/devman +MACHINE ?= aquila +AP_KERN_VER ?= S5PC110_2_6_29 + +ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS))) + CFLAGS += -O0 + CXXFLAGS += -O0 +else + CFLAGS += -O2 + CXXFLAGS += -O2 +endif + +LDFLAGS += -Wl,--rpath=$(PREFIX)/lib -Wl,--as-needed + + +configure: configure-stamp +configure-stamp: + dh_testdir + # Add here commands to configure the package. + CFLAGS="$(CFLAGS) -D${AP_KERN_VER}" CXXFLAGS="$(CXXFLAGS)" LDFLAGS="$(LDFLAGS)" cmake . -DCMAKE_INSTALL_PREFIX=$(PREFIX) -DCMAKE_DEVMAN_RSRC_PREFIX=$(DEVMAN_RSRCDIR) -DCMAKE_MACHINE=${MACHINE} -DCMAKE_DATADIR=${DATADIR} + + touch configure-stamp + +build: build-stamp + +build-stamp: configure-stamp + dh_testdir + + # Add here commands to compile the package. + $(MAKE) + + for f in `find $(CURDIR)/debian/ -name "*.in"`; do \ + cat $$f > $${f%.in}; \ + sed -i -e "s#@PREFIX@#$(PREFIX)#g" $${f%.in}; \ + sed -i -e "s#@DATADIR@#$(DATADIR)#g" $${f%.in}; \ + done + + touch $@ + +clean: + dh_testdir + dh_testroot + rm -f build-stamp configure-stamp + + # Add here commands to clean up after the build process. + -$(MAKE) clean + rm -rf CMakeCache.txt + rm -rf CMakeFiles + rm -rf cmake_install.cmake + rm -rf Makefile + rm -rf install_manifest.txt + rm -rf test/CMakeFiles + rm -rf test/cmake_install.cmake + rm -rf test/Makefile + rm -rf test/install_manifest.txt + + rm -rf *.so + rm -rf *.pc + rm -rf debian/*.install + rm -rf debian/*.postinst + rm -rf debian/*.postrm + rm -rf udev-files/*.rules + + dh_clean + +install: build + dh_testdir + dh_testroot + dh_clean -k + dh_installdirs + + # Add here commands to install the package into debian/wavplayer. + $(MAKE) DESTDIR=$(CURDIR)/debian/tmp install + mkdir -p $(CURDIR)/debian/tmp/etc/rc.d/rc3.d/ + mkdir -p $(CURDIR)/debian/tmp/etc/rc.d/rc4.d/ + ln -s ../init.d/devman $(CURDIR)/debian/tmp/etc/rc.d/rc3.d/S10devman + ln -s ../init.d/devman $(CURDIR)/debian/tmp/etc/rc.d/rc4.d/S10devman + + + +# Build architecture-independent files here. +binary-indep: build install +# We have nothing to do by default. + +# Build architecture-dependent files here. +binary-arch: build install + dh_testdir + dh_testroot + dh_installchangelogs + dh_installdocs + dh_installexamples + dh_install --sourcedir=debian/tmp +# dh_installmenu +# dh_installdebconf +# dh_installlogrotate +# dh_installemacsen +# dh_installpam +# dh_installmime +# dh_python +# dh_installinit +# dh_installcron +# dh_installinfo + dh_installman + dh_link +# dh_strip + dh_strip --dbg-package=libdevman-dbg + dh_compress + dh_fixperms +# dh_perl + dh_makeshlibs + dh_installdeb + dh_shlibdeps + dh_gencontrol + dh_md5sums + dh_builddeb + +binary: binary-indep binary-arch +.PHONY: build clean binary-indep binary-arch binary install configure diff --git a/device_engine.c b/device_engine.c new file mode 100644 index 0000000..58870f0 --- /dev/null +++ b/device_engine.c @@ -0,0 +1,242 @@ +/* + * devman + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: DongGi Jang + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * +*/ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "devlog.h" +#include "device_engine.h" + +struct device *dev_head = NULL; +#define BUFF_MAX 255 + +void add_dev(struct device *dev) +{ + dev->next = dev_head; + dev_head = dev; +} + +void print_devices() +{ + struct device *dev; + dev = dev_head; + + while (dev) { + DBG("%s - %d", dev->devname, dev->devtype); + dev = dev->next; + } +} + +void reset_devtype() +{ + struct device *dev; + dev = dev_head; + + while (dev) { + dev->devtype = -1; + dev = dev->next; + } +} + +struct device *find_device(struct device *root_dev, devtype_t devtype) +{ + struct device *dev; + + if (devtype == -1) + return NULL; + + if (root_dev == NULL) + dev = dev_head; + else + dev = root_dev; + + while (dev) { + DBG("devname = %s %d %d", dev->devname, dev->devtype, devtype); + if (dev->devtype == devtype) + return dev; + dev = dev->next; + } + + return NULL; +} + +int find_sysfs_node(char *path, char *node_name) +{ + DIR *dp; + struct dirent *entry; + + dp = opendir(path); + if (dp == NULL) { + DBG("path is not existed : %s", path); + return -1; + } + + while ((entry = readdir(dp)) != NULL) { + if (strncmp(entry->d_name, ".", 1) == 0 || + strncmp(entry->d_name, "..", 2) == 0) + continue; + else + break; + } + + /* copy node name */ + if (entry != NULL) { + if (node_name != NULL) + strncpy(node_name, entry->d_name,PATH_MAX); + + } else { + DBG("sysfs node not existed"); + if (closedir(dp) != 0) + DBG("Unable to close directory"); + return -1; + } + + if (closedir(dp) != 0) + DBG("Unable to close directory"); + return 0; +} + +int set_devtype(char *devname, devtype_t devtype) +{ + int ret; + struct device *dev; + dev = dev_head; + + while (dev) { + if (strstr(dev->devname, devname)) { + if ((strstr(dev->devname, "auto") != NULL) && + (dev->probe != NULL)) { + ret = dev->probe(); + if (ret < 0) { + DBG("auto probe failed"); + return -1; + } + } + + dev->devtype = devtype; + return 0; + } + dev = dev->next; + } + + return -1; +} + +static int sys_read_buf(char *file, char *buf) +{ + int fd; + int r; + + fd = open(file, O_RDONLY); + if (fd == -1) { + ERR("%s open error: %s", file, strerror(errno)); + return -1; + } + + r = read(fd, buf, BUFF_MAX); + if ((r >= 0) && (r < BUFF_MAX)) + buf[r] = '\0'; + else { + ERR("%s read error: %s", file, strerror(errno)); + return -1; + } + + close(fd); + INFO("read %s, value= %s", file, buf); + return 0; +} + +static int sys_write_buf(char *file, char *buf) +{ + int fd; + int r; + + fd = open(file, O_WRONLY); + if (fd == -1) { + ERR("%s open error: %s", file, strerror(errno)); + return -1; + } + + r = write(fd, buf, strlen(buf)); + close(fd); + if (r < 0) { + ERR("%s write error: %s", file, strerror(errno)); + return -1; + } + INFO("write %s, value= %s", file, buf); + return 0; +} + +int sys_get_int(char *fname, int *val) +{ + char buf[BUFF_MAX]; + + if (sys_read_buf(fname, buf) == 0) { + *val = atoi(buf); + return 0; + } else { + *val = -1; + return -1; + } +} + +char *sys_get_str(char *fname) +{ + char buf[BUFF_MAX]; + char *r = NULL; + + if (sys_read_buf(fname, buf) == 0) + r = strdup((char *)buf); + + return r; +} + +int sys_set_int(char *fname, int val) +{ + char buf[BUFF_MAX]; + int r = -1; + snprintf(buf, sizeof(buf), "%d", val); + + if (sys_write_buf(fname, buf) == 0) + r = 0; + + return r; +} + +int sys_set_str(char *fname, char *val) +{ + int r = -1; + + if (val != NULL) { + if (sys_write_buf(fname, val) == 0) + r = 0; + } + + return r; +} diff --git a/device_engine.h b/device_engine.h new file mode 100644 index 0000000..f130704 --- /dev/null +++ b/device_engine.h @@ -0,0 +1,50 @@ +/* + * devman + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: DongGi Jang + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * +*/ + + +#ifndef API +#define API __attribute__ ((visibility("default"))) +#endif + +#include +#include "devman.h" + +struct device { + devtype_t devtype; + char *devname; + int (*set_int) (int property, int val); + int (*get_int) (int property, int *val); + int (*probe) (void); + struct device *next; +}; + +void add_dev(struct device *dev); +struct device *find_device(struct device *root_dev, devtype_t devtype); +int set_devtype(char *devname, devtype_t devtype); +void reset_devtype(); +void print_devices(); + +int find_sysfs_node(char *path, char *node_name); + +int sys_get_int(char *fname, int *val); +int sys_set_int(char *fname, int val); +char *sys_get_str(char *fname); +int sys_set_str(char *fname, char *val); diff --git a/device_generic.h b/device_generic.h new file mode 100644 index 0000000..f914769 --- /dev/null +++ b/device_generic.h @@ -0,0 +1,60 @@ +/* + * devman + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: DongGi Jang + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * +*/ + + +#ifndef __DEVICE_GENERIC_H__ +#define __DEVICE_GENERIC_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Jack */ + int generic_jack_interface_get(char *nodename, int prop, int *val); + int generic_jack_interface_set(char *nodename, int prop, int val); + +/* Power Supply */ + int generic_class_power_supply_get(char *nodename, int prop, int *val); + +/* Touch panel */ + int generic_class_touchkey_get(char *nodename, int *val); + int generic_class_touchkey_set(char *nodename, int val); + +/* LCD */ + int generic_class_lcd_get(char *nodename, int prop, int *val); + int generic_class_lcd_set(char *nodename, int prop, int val); + +/* Backlight */ + int generic_class_backlight_get(char *nodename, int prop, int *val); + int generic_class_backlight_set(char *nodename, int prop, int val); + +/* LED */ + int generic_class_led_get(char *nodename, int prop, int *val); + int generic_class_led_set(char *nodename, int prop, int val); + +/* Generic Motor */ + int generic_class_haptic_get(char *nodename, int prop, int *val); + int generic_class_haptic_set(char *nodename, int prop, int val); + +#ifdef __cplusplus +} +#endif +#endif /* __DEVICE_GENERIC_H__ */ diff --git a/device_haptic.c b/device_haptic.c new file mode 100644 index 0000000..5e8ceaf --- /dev/null +++ b/device_haptic.c @@ -0,0 +1,1852 @@ +/* + * devman + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: DongGi Jang + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * +*/ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "devlog.h" +#include "device_haptic.h" +#include "devman.h" +#include "devman_haptic.h" +#include "devman_haptic_ext.h" +/* START: Will be excluded by removing pattern */ +#include "device_haptic_tsp4000_pattern.h" +/* END: Will be excluded */ + +#ifndef EXTAPI +#define EXTAPI __attribute__ ((visibility("default"))) +#endif /* EXTAPI */ + + +#define HAPTIC_DEVICE_NODE_PATH "/dev/tspdrv" +#define HAPTIC_MODULE_PATH "/usr/lib/devman/libdevman_haptic.so" + +/* START: Will be removed by removing pattern */ +#define HAPTIC_PLAY_FILE_EXT ".ivt" +#define HAPTIC_BUILT_IN_FILE_PATH "/usr/share/immersion" + +struct g_pivt_list_t +{ + char file_name[NAME_MAX]; + unsigned char *ivt_pt; + int priority; +}; + +struct g_pivt_list_t g_haptic_internal_pattern_list[EFFCTVIBE_PATTERN_END] = { + /*for BeatUX*/ + [EFFCTVIBE_TOUCH] = { "/01_Touch/touch_20ms_sharp", touch_ivt, 15}, + [EFFCTVIBE_HW_TOUCH] = { "/01_Touch/HW_touch_30ms_sharp", hw_touch_ivt, 15}, + + [EFFCTVIBE_NOTIFICATION] = { "/02_Notification/Notification", noti_ivt, 7}, + [EFFCTVIBE_INCOMING_CALL01] = { "/02_Notification/Incoming call_01", incomming_01_ivt, 7}, + [EFFCTVIBE_INCOMING_CALL02] = { "/02_Notification/Incoming call_02", incomming_02_ivt, 7}, + [EFFCTVIBE_INCOMING_CALL03] = { "/02_Notification/Incoming call_03", incomming_03_ivt, 7}, + + [EFFCTVIBE_ALERTS_CALL] = { "/03_Operation/Alerts on Call", alerts_call_ivt, 15}, + [EFFCTVIBE_OPERATION] = { "/03_Operation/Operation", operation_ivt, 7}, + [EFFCTVIBE_SILENT_MODE] = { "/03_Operation/Silent mode", silent_ivt, 7}, +}; +/* END: Will be removed */ + +static int has_haptic_module = -1; +static int master_callback_enable = 0; +static int setting_fb_level = -1; +static int device_handle_count = 0; +static void *dlopen_handle; + +enum { + MODE_DEFAULT = 0x0000, + MODE_FEEDBACK_LEVEL_CHECK_DISABLE = 0x0001, +}; + +static void (*_haptic_internal_prepare_node) (void); +static int (*_haptic_internal_play_buffer) (int, const unsigned char *, int, int, int); +static int (*_haptic_internal_play_file) (int, const char *, int, int, int); +static int (*_haptic_internal_play_monotone) (int, int, int, int); +static int (*_haptic_internal_get_buffer_duration) (int, const unsigned char *, int *); +static int (*_haptic_internal_get_file_duration) (int, const char *, int *); +static int (*_haptic_internal_initialize) (void); +static int (*_haptic_internal_terminate) (void); +static int (*_haptic_internal_open_composite_device) (int *, int, int *); +static int (*_haptic_internal_open_device) (int, int*); +static int (*_haptic_internal_set_device_property_string) (int, int, const char *); +static int (*_haptic_internal_set_device_property_int32) (int, int, int); +static int (*_haptic_internal_set_device_property_bool) (int, int, unsigned char); +static int (*_haptic_internal_get_device_property_string) (int, int, int, char *); +static int (*_haptic_internal_get_device_property_int32) (int, int, int *); +static int (*_haptic_internal_get_device_property_bool) (int, int, unsigned char *); +static int (*_haptic_internal_play_IVT_effect) (int, const unsigned char *, int, int *); +static int (*_haptic_internal_play_IVT_effect_repeat) (int, const unsigned char *, int, unsigned char, int *); +static int (*_haptic_internal_close_device) (int); +static int (*_haptic_internal_stop_all_playing_effects) (int); +static int (*_haptic_internal_play_periodic_effect) (int, int, int, int, int, int, int, int, int, int *); +static int (*_haptic_internal_get_device_count) (void); +static int (*_haptic_internal_get_device_state) (int, int *); +static int (*_haptic_internal_get_device_capability_bool) (int, int, unsigned char *); +static int (*_haptic_internal_get_device_capability_int32) (int, int, int *); +static int (*_haptic_internal_get_device_capability_string) (int, int, int, char *); +static int (*_haptic_internal_get_IVT_effect_count) (const unsigned char *); +static int (*_haptic_internal_get_IVT_effect_name) (const unsigned char *, int, int, char *); +static int (*_haptic_internal_get_IVT_effect_name_u) (const unsigned char *, int, int, unsigned short *); +static int (*_haptic_internal_get_IVT_effect_index_from_name) (const unsigned char *, const char *, int *); +static int (*_haptic_internal_get_IVT_effect_index_from_name_u) (const unsigned char *, const unsigned short *, int *); +static int (*_haptic_internal_stop_playing_effect) (int, int); +static int (*_haptic_internal_get_IVT_effect_type) (const unsigned char *, int, int *); +static int (*_haptic_internal_get_IVT_magsweep_effect_definition) (const unsigned char *, int, int *, int *, int *, int *, int *, int *, int *); +static int (*_haptic_internal_get_IVT_periodic_effect_definition) (const unsigned char *, int, int *, int *, int *, int *, int *, int *, int *, int *); +static int (*_haptic_internal_get_IVT_effect_duration) (const unsigned char *, int, int *); +static int (*_haptic_internal_play_magsweep_effect) (int, int, int, int, int, int, int, int, int *); +static int (*_haptic_internal_play_periodic_effect) (int, int, int, int, int, int, int, int, int, int *); +static int (*_haptic_internal_modify_playing_magsweep_effect) (int, int, int, int, int, int, int, int, int); +static int (*_haptic_internal_modify_playing_periodic_effect) (int, int, int, int, int, int, int, int, int, int); +static int (*_haptic_internal_create_streaming_effect) (int, int *); +static int (*_haptic_internal_destroy_streaming_effect) (int, int); +static int (*_haptic_internal_play_streaming_sample) (int, int, const unsigned char *, int); +static int (*_haptic_internal_play_streaming_sample_with_offset) (int, int, const unsigned char *, int, int); +static int (*_haptic_internal_save_IVT_file) (const unsigned char *, const char *); +static int (*_haptic_internal_delete_IVT_file) (const char *); +static int (*_haptic_internal_pause_playing_effect) (int, int); +static int (*_haptic_internal_resume_paused_effect) (int, int); +static int (*_haptic_internal_get_effect_state) (int, int, int *); +static int (*_haptic_internal_get_IVT_size) (const unsigned char *, int); +static int (*_haptic_internal_initialize_IVT_buffer) (unsigned char *, int); +static int (*_haptic_internal_insert_IVT_element) (unsigned char *, int, int, const HapticElement *); +static int (*_haptic_internal_insert_IVT_element2) (unsigned char *, int, int, const HapticElement2 *); +static int (*_haptic_internal_insert_IVT_element3) (unsigned char *, int, int, const HapticElement3 *); +static int (*_haptic_internal_read_IVT_element) (const unsigned char *, int, int, int, HapticElement *); +static int (*_haptic_internal_read_IVT_element2) (const unsigned char *, int, int, int, HapticElement2 *); +static int (*_haptic_internal_read_IVT_element3) (const unsigned char *, int, int, int, HapticElement3 *); +static int (*_haptic_internal_remove_IVT_element) (unsigned char *, int, int, int); + +/* START of Static Function Section */ +static int __get_master_strength_value() +{ + int input_strength = 0; + + switch (setting_fb_level) { + case SETTING_VIB_FEEDBACK_LEVEL0: + DBG("get setting value = 0 , so can not vibe"); + return 0; + break; + case SETTING_VIB_FEEDBACK_LEVEL1: + input_strength = VIBE_FEEDBACK_LEVEL_1; + break; + + case SETTING_VIB_FEEDBACK_LEVEL2: + input_strength = VIBE_FEEDBACK_LEVEL_2; + break; + + case SETTING_VIB_FEEDBACK_LEVEL3: + input_strength = VIBE_FEEDBACK_LEVEL_3; + break; + + case SETTING_VIB_FEEDBACK_LEVEL4: + input_strength = VIBE_FEEDBACK_LEVEL_4; + break; + + case SETTING_VIB_FEEDBACK_LEVEL5: + input_strength = VIBE_FEEDBACK_LEVEL_5; + break; + + default: + ERR("error get VCONF_SETAPPL_VIB_FEEDBACK_INT value (= %d) invalid", setting_fb_level); + return -2; + break; + } + + return input_strength; +} + +static int __convert_strength_level(int type, int base_level) +{ + int convert_strength = 0; + + switch (base_level) { + case 0: + ERR("Input base_level == 0(:%d)\n", base_level); + break; + + case HAPTIC_FEEDBACK_LEVEL_1: + convert_strength = VIBE_FEEDBACK_LEVEL_1; + break; + + case HAPTIC_FEEDBACK_LEVEL_2: + convert_strength = VIBE_FEEDBACK_LEVEL_2; + break; + + case HAPTIC_FEEDBACK_LEVEL_3: + convert_strength = VIBE_FEEDBACK_LEVEL_3; + break; + + case HAPTIC_FEEDBACK_LEVEL_4: + convert_strength = VIBE_FEEDBACK_LEVEL_4; + break; + + case HAPTIC_FEEDBACK_LEVEL_5: + convert_strength = VIBE_FEEDBACK_LEVEL_5; + break; + + default: + ERR("error invalid convertable value (%d)", base_level); + return -2; + } + + return convert_strength; +} + +static void __haptic_changed_cb(keynode_t *node, void *data) +{ + int feedback_level; + + DBG("[haptic_changed_cb] changed key = %s\n", + vconf_keynode_get_name(node)); + + if (vconf_keynode_get_type(node) == VCONF_TYPE_INT) { + + feedback_level = vconf_keynode_get_int(node); + + if (feedback_level == -1) { + ERR(" [haptic_changed_cb] Err vconf_keynode_get_int fail from key in haptic_changed_cb : %s , fail state : %d ,so set default level", vconf_keynode_get_name(node), feedback_level); + return; + } + DBG("[haptic_changed_cb] get value : %d , from key : %s", + feedback_level, vconf_keynode_get_name(node)); + + setting_fb_level = feedback_level; + } else { + ERR("[haptic_changed_cb] Err changed key_type miss-match!! read_type : %d", vconf_keynode_get_type(node)); + } +} +/* END of Static Function Section */ + + +/* START: devman_haptic APIs */ +EXTAPI +int device_haptic_open(haptic_dev_idx dev_idx, unsigned int mode) +{ + int status; + int device_index = dev_idx >> 1; + int device_handle; + + if (device_handle_count == 0) { + if (has_haptic_module == 1) { + _haptic_internal_prepare_node(); + + if (_haptic_internal_initialize() < 0) { + ERR("_haptic_internal_initialize() failed"); + return HAPTIC_FAIL; + } + } + + if (mode & MODE_FEEDBACK_LEVEL_CHECK_DISABLE) { + pid_t cpid; + cpid = getpid(); + DBG("NOT USE MAIN VIB_FEEDBACK_CHECK ROUTINE !!, at pid : %d", cpid); + setting_fb_level = SETTING_VIB_FEEDBACK_LEVEL3; + } else if (master_callback_enable == 0) { + status = vconf_get_int(VCONFKEY_SETAPPL_VIB_FEEDBACK_INT, &setting_fb_level); + if (status < 0) { + DBG(" vconf_get_int fail from key : %s , fail state : %d ,so set default level", VCONFKEY_SETAPPL_VIB_FEEDBACK_INT, status); + setting_fb_level = SETTING_VIB_FEEDBACK_LEVEL3; + } + DBG("get value : %d , from key : %s", setting_fb_level, VCONFKEY_SETAPPL_VIB_FEEDBACK_INT); + + status = vconf_notify_key_changed (VCONFKEY_SETAPPL_VIB_FEEDBACK_INT, __haptic_changed_cb, NULL); + if (status < 0) { + ERR("Device_haptic_open vconf_notify_key_changed fail\n"); + return HAPTIC_FAIL; + } + + master_callback_enable = 1; + } + } + + if (has_haptic_module == 1) { + if (dev_idx == DEV_IDX_ALL) { + status = _haptic_internal_open_composite_device(NULL, device_index, &device_handle); + if(HAPTIC_FAILED(status)) { + ERR("_haptic_internal_open_composite_device() Failed: %d", status); + return HAPTIC_FAIL; + } + } else { + status = _haptic_internal_open_device(device_index, &device_handle); + if(HAPTIC_FAILED(status)) { + ERR("_haptic_internal_open_device() Failed: %d", status); + return HAPTIC_FAIL; + } + } + + ++device_handle_count; + return device_handle; + } + + ++device_handle_count; + return DEFAULT_DEVICE_HANDLE; +} + +EXTAPI +int device_haptic_close(int device_handle) +{ + int status; + + if (device_handle_count == 0) { + ERR("Haptic device already closed"); + return HAPTIC_NOT_OPENED; + } + + if (has_haptic_module == 1) { + status = _haptic_internal_close_device(device_handle); + if(HAPTIC_FAILED(status)) { + ERR("_haptic_internal_close_device(0) fail: %d", status); + return HAPTIC_FAIL; + } + } + + --device_handle_count; + if (device_handle_count == 0) { + if (has_haptic_module == 1) { + status = _haptic_internal_terminate(); + if(HAPTIC_FAILED(status)) { + ERR("_haptic_internal_terminate(0) fail: %d", status); + return HAPTIC_FAIL; + } + } + + if (master_callback_enable == 1) { + status = vconf_ignore_key_changed(VCONFKEY_SETAPPL_VIB_FEEDBACK_INT, __haptic_changed_cb); + if (status < 0) { + ERR("Device_haptic_close vconf_ignore_key_changed fail\n"); + return HAPTIC_FAIL; + } + master_callback_enable = 0; + } + } + + return HAPTIC_SUCCESS; +} + +EXTAPI +int device_haptic_play_buffer(int device_handle, const unsigned char *vibe_buffer, int iteration, int feedback_level) +{ + if (device_handle_count == 0) { + ERR("Haptic device is not opened yet"); + return HAPTIC_NOT_OPENED; + } + + if (has_haptic_module == 0) { + ERR("%s() is not supported without specific haptic module", __func__); + return HAPTIC_NOT_SUPPORTED; + } + + return _haptic_internal_play_buffer(device_handle, vibe_buffer, iteration, feedback_level, HAPTIC_MIN_DEVICE_PRIORITY); +} + +EXTAPI +int device_haptic_play_file(int device_handle, const char *file_name, int iteration, int feedback_level) +{ + if (device_handle_count == 0) { + ERR("Haptic device is not opened yet"); + return HAPTIC_NOT_OPENED; + } + + if (has_haptic_module == 0) { + ERR("%s() is not supported without specific haptic module", __func__); + return HAPTIC_NOT_SUPPORTED; + } + + return _haptic_internal_play_file(device_handle, file_name, iteration, feedback_level, HAPTIC_MIN_DEVICE_PRIORITY); +} + +EXTAPI +int device_haptic_play_pattern(int device_handle, int pattern, int iteration, int feedback_level) +{ + char file_name[NAME_MAX]; + int priority = -1; + int input_feedback_level = feedback_level; + + if (device_handle_count == 0) { + ERR("Haptic device is not opened yet"); + return HAPTIC_NOT_OPENED; + } + + if (has_haptic_module == 0) { + ERR("%s() is not supported without specific haptic module", __func__); + return HAPTIC_NOT_SUPPORTED; + } + + if (feedback_level == HAPTIC_FEEDBACK_LEVEL_AUTO) { + input_feedback_level = -setting_fb_level; + } + + /* Set Priority */ + if (!g_haptic_internal_pattern_list[pattern].priority) { + priority = HAPTIC_MIN_DEVICE_PRIORITY; + } else { + priority = g_haptic_internal_pattern_list[pattern].priority; + } + + if (!g_haptic_internal_pattern_list[pattern].ivt_pt) { + /* Pass filename insted of buffer pointer */ + if (0 > snprintf(file_name, NAME_MAX, "%s%s%s", HAPTIC_BUILT_IN_FILE_PATH, g_haptic_internal_pattern_list[pattern].file_name, HAPTIC_PLAY_FILE_EXT)) + { + ERR("snprintf fail in EFFCTVIBE_SET_EFFECT_TYPE"); + return HAPTIC_FAIL; + } + + return _haptic_internal_play_file(device_handle, file_name, iteration, input_feedback_level, HAPTIC_MIN_DEVICE_PRIORITY); + } + + return _haptic_internal_play_buffer(device_handle, g_haptic_internal_pattern_list[pattern].ivt_pt, iteration, input_feedback_level, priority); +} + +EXTAPI +int device_haptic_stop_play(int device_handle) +{ + int status; + + if (device_handle_count == 0) { + ERR("Haptic device is not opened yet"); + return HAPTIC_NOT_OPENED; + } + + if (has_haptic_module == 1) { + status = _haptic_internal_stop_all_playing_effects(device_handle); + if(HAPTIC_FAILED(status)) { + ERR("_haptic_internal_stop_all_playing_effects(0) fail: %d", status); + return HAPTIC_FAIL; + } + } else { + status = device_set_property(DEVTYPE_HAPTIC, HAPTIC_PROP_ENABLE, 0); + if (status < 0) { + ERR("Haptic device stop failed: %d", status); + return HAPTIC_FAIL; + } + } + + return HAPTIC_SUCCESS; +} + +EXTAPI +int device_haptic_play_monotone(int device_handle, int duration) +{ + int status; + int input_strength; + int effect_handle; + + if (device_handle_count == 0) { + ERR("Haptic device is not opened yet"); + return HAPTIC_NOT_OPENED; + } + + if (has_haptic_module == 1) { + status = _haptic_internal_play_monotone(device_handle, duration, -setting_fb_level, 0x05); + if(HAPTIC_FAILED(status)) { + ERR("_haptic_internal_play_monotone(0) fail: %d", status); + return HAPTIC_FAIL; + } + } else { + input_strength = __get_master_strength_value(); + if (input_strength < 0) { + ERR("convert_strength_level fail : %d", input_strength); + return HAPTIC_FAIL; + } + + status = device_set_property(DEVTYPE_HAPTIC, HAPTIC_PROP_LEVEL, input_strength); + if (status < 0) { + ERR(" haptic_set_level for strength:%d (error:%d) \n", input_strength, status); + return HAPTIC_FAIL; + } + + status = device_set_property(DEVTYPE_HAPTIC, HAPTIC_PROP_ONESHOT, duration); + if (status < 0) { + ERR(" haptic_oneshot for duration:%d (error:%d) \n", duration, status); + return HAPTIC_FAIL; + } + } + + return HAPTIC_SUCCESS; +} + +EXTAPI +int device_haptic_get_buffer_duration(int device_handle, const unsigned char *vibe_buffer, int *duration) +{ + if (device_handle_count == 0) { + ERR("Haptic device is not opened yet"); + return HAPTIC_NOT_OPENED; + } + + if (has_haptic_module == 0) { + ERR("%s() is not supported without specific haptic module", __func__); + return HAPTIC_NOT_SUPPORTED; + } + + return _haptic_internal_get_buffer_duration(device_handle, vibe_buffer, duration); +} + +EXTAPI +int device_haptic_get_file_duration(int device_handle, const char *file_name, int *duration) +{ + if (device_handle_count == 0) { + ERR("Haptic device is not opened yet"); + return HAPTIC_NOT_OPENED; + } + + if (has_haptic_module == 0) { + ERR("%s() is not supported without specific haptic module", __func__); + return HAPTIC_NOT_SUPPORTED; + } + + return _haptic_internal_get_file_duration(device_handle, file_name, duration); +} + +EXTAPI +int device_haptic_get_pattern_duration(int device_handle, int pattern, int *duration) +{ + if (device_handle_count == 0) { + ERR("Haptic device is not opened yet"); + return HAPTIC_NOT_OPENED; + } + + if (has_haptic_module == 0) { + ERR("%s() is not supported without specific haptic module", __func__); + return HAPTIC_NOT_SUPPORTED; + } + int status; + char file_name[NAME_MAX]; + + if (!g_haptic_internal_pattern_list[pattern].ivt_pt) { + /* Pass filename insted of buffer pointer */ + if (0 > snprintf(file_name, NAME_MAX, "%s%s%s", HAPTIC_BUILT_IN_FILE_PATH, g_haptic_internal_pattern_list[pattern].file_name, HAPTIC_PLAY_FILE_EXT)) + { + ERR("snprintf fail in EFFCTVIBE_SET_EFFECT_TYPE"); + return HAPTIC_FAIL; + } + + return _haptic_internal_get_file_duration(device_handle, file_name, duration); + } + + return _haptic_internal_get_buffer_duration(device_handle, g_haptic_internal_pattern_list[pattern].ivt_pt, duration); +} + +EXTAPI +int device_haptic_get_device_count() +{ + int status; + int device_count = -1; + + if (has_haptic_module == 0) { + return DEFAULT_MOTOR_COUNT; + } + + if (device_handle_count == 0) { + _haptic_internal_prepare_node(); + + status = _haptic_internal_initialize(); + if (status < 0) { + return HAPTIC_FAIL; + } + /* Get device count */ + device_count = _haptic_internal_get_device_count(); + if(HAPTIC_FAILED(device_count)) { + ERR("_haptic_internal_get_device_count(0) fail: %d",status); + return HAPTIC_FAIL; + } + + status = _haptic_internal_terminate(); + if (status < 0) { + return HAPTIC_FAIL; + } + } else { + device_count = _haptic_internal_get_device_count(); + if(HAPTIC_FAILED(device_count)) { + ERR("_haptic_internal_get_device_count(0) fail: %d",status); + return HAPTIC_FAIL; + } + } + + return device_count; +} +/* END: devman_haptic APIs */ + + +/* START: devman_haptic_ext APIs */ +EXTAPI +int device_haptic_get_device_state(int device_index, int *state) +{ + int status; + int index = device_index >> 1; + + if (device_handle_count == 0) { + ERR("Haptic device is not opened yet"); + return HAPTIC_NOT_OPENED; + } + + if (has_haptic_module == 0) { + ERR("%s() is not supported without specific haptic module", __func__); + return HAPTIC_NOT_SUPPORTED; + } + + return _haptic_internal_get_device_state(index, state); +} + +EXTAPI +int device_haptic_get_device_capability_bool(int device_index, int device_cap_type, unsigned char *device_cap_value) +{ + int status; + int index = device_index >> 1; + + if (device_handle_count == 0) { + ERR("Haptic device is not opened yet"); + return HAPTIC_NOT_OPENED; + } + + if (has_haptic_module == 0) { + ERR("%s() is not supported without specific haptic module", __func__); + return HAPTIC_NOT_SUPPORTED; + } + + return _haptic_internal_get_device_capability_bool(index, device_cap_type, device_cap_value); +} + +EXTAPI +int device_haptic_get_device_capability_int32(int device_index, int device_cap_type, int *device_cap_value) +{ + int status; + int index = device_index >> 1; + + if (device_handle_count == 0) { + ERR("Haptic device is not opened yet"); + return HAPTIC_NOT_OPENED; + } + + if (has_haptic_module == 0) { + ERR("%s() is not supported without specific haptic module", __func__); + return HAPTIC_NOT_SUPPORTED; + } + + return _haptic_internal_get_device_capability_int32(index, device_cap_type, device_cap_value); +} + +EXTAPI +int device_haptic_get_device_capability_string(int device_index, int device_cap_type, int size, char *device_cap_value) +{ + int status; + int index = device_index >> 1; + + if (device_handle_count == 0) { + ERR("Haptic device is not opened yet"); + return HAPTIC_NOT_OPENED; + } + + if (has_haptic_module == 0) { + ERR("%s() is not supported without specific haptic module", __func__); + return HAPTIC_NOT_SUPPORTED; + } + + return _haptic_internal_get_device_capability_string(index, device_cap_type, size, device_cap_value); +} + +EXTAPI +int device_haptic_get_device_property_bool(int device_handle, int device_prop_type, unsigned char *device_prop_value) +{ + int status; + + if (device_handle_count == 0) { + ERR("Haptic device is not opened yet"); + return HAPTIC_NOT_OPENED; + } + + if (has_haptic_module == 0) { + ERR("%s() is not supported without specific haptic module", __func__); + return HAPTIC_NOT_SUPPORTED; + } + + return _haptic_internal_get_device_property_bool(device_handle, device_prop_type, device_prop_value); +} + +EXTAPI +int device_haptic_set_device_property_bool(int device_handle, int device_prop_type, unsigned char device_prop_value) +{ + int status; + + if (device_handle_count == 0) { + ERR("Haptic device is not opened yet"); + return HAPTIC_NOT_OPENED; + } + + if (has_haptic_module == 0) { + ERR("%s() is not supported without specific haptic module", __func__); + return HAPTIC_NOT_SUPPORTED; + } + + return _haptic_internal_set_device_property_bool(device_handle, device_prop_type, device_prop_value); +} + +EXTAPI +int device_haptic_get_device_property_int32(int device_handle, int device_prop_type, int *device_prop_value) +{ + int status; + + if (device_handle_count == 0) { + ERR("Haptic device is not opened yet"); + return HAPTIC_NOT_OPENED; + } + + if (has_haptic_module == 0) { + ERR("%s() is not supported without specific haptic module", __func__); + return HAPTIC_NOT_SUPPORTED; + } + + return _haptic_internal_get_device_property_int32(device_handle, device_prop_type, device_prop_value); +} + +EXTAPI +int device_haptic_set_device_property_int32(int device_handle, int device_prop_type, int device_prop_value) +{ + int status; + + if (device_handle_count == 0) { + ERR("Haptic device is not opened yet"); + return HAPTIC_NOT_OPENED; + } + + if (has_haptic_module == 0) { + ERR("%s() is not supported without specific haptic module", __func__); + return HAPTIC_NOT_SUPPORTED; + } + + return _haptic_internal_set_device_property_int32(device_handle, device_prop_type, device_prop_value); +} + +EXTAPI +int device_haptic_get_device_property_string(int device_handle, int device_prop_type, int size, char *device_prop_value) +{ + int status; + + if (device_handle_count == 0) { + ERR("Haptic device is not opened yet"); + return HAPTIC_NOT_OPENED; + } + + if (has_haptic_module == 0) { + ERR("%s() is not supported without specific haptic module", __func__); + return HAPTIC_NOT_SUPPORTED; + } + + return _haptic_internal_get_device_property_string(device_handle, device_prop_type, size, device_prop_value); +} + +EXTAPI +int device_haptic_set_device_property_string(int device_handle, int device_prop_type, const char *device_prop_value) +{ + int status; + + if (device_handle_count == 0) { + ERR("Haptic device is not opened yet"); + return HAPTIC_NOT_OPENED; + } + + if (has_haptic_module == 0) { + ERR("%s() is not supported without specific haptic module", __func__); + return HAPTIC_NOT_SUPPORTED; + } + + return _haptic_internal_set_device_property_string(device_handle, device_prop_type, device_prop_value); +} + +EXTAPI +int device_haptic_get_effect_count(const unsigned char *haptic_buffer) +{ + int status; + + if (device_handle_count == 0) { + ERR("Haptic device is not opened yet"); + return HAPTIC_NOT_OPENED; + } + + if (has_haptic_module == 0) { + ERR("%s() is not supported without specific haptic module", __func__); + return HAPTIC_NOT_SUPPORTED; + } + + return _haptic_internal_get_IVT_effect_count(haptic_buffer); +} + +EXTAPI +int device_haptic_get_effect_name(const unsigned char *haptic_buffer, int effect_index, int size, char *effect_name) +{ + int status; + + if (device_handle_count == 0) { + ERR("Haptic device is not opened yet"); + return HAPTIC_NOT_OPENED; + } + + if (has_haptic_module == 0) { + ERR("%s() is not supported without specific haptic module", __func__); + return HAPTIC_NOT_SUPPORTED; + } + + return _haptic_internal_get_IVT_effect_name(haptic_buffer, effect_index, size, effect_name); +} + +EXTAPI +int device_haptic_get_effect_name_u(const unsigned char *haptic_buffer, int effect_index, int size, unsigned short *effect_name) +{ + int status; + + if (device_handle_count == 0) { + ERR("Haptic device is not opened yet"); + return HAPTIC_NOT_OPENED; + } + + if (has_haptic_module == 0) { + ERR("%s() is not supported without specific haptic module", __func__); + return HAPTIC_NOT_SUPPORTED; + } + + return _haptic_internal_get_IVT_effect_name_u(haptic_buffer, effect_index, size, effect_name); +} + +EXTAPI +int device_haptic_get_effect_index_from_name(const unsigned char *haptic_buffer, char const *effect_name, int *effect_index) +{ + int status; + + if (device_handle_count == 0) { + ERR("Haptic device is not opened yet"); + return HAPTIC_NOT_OPENED; + } + + if (has_haptic_module == 0) { + ERR("%s() is not supported without specific haptic module", __func__); + return HAPTIC_NOT_SUPPORTED; + } + + return _haptic_internal_get_IVT_effect_index_from_name(haptic_buffer, effect_name, effect_index); +} + +EXTAPI +int device_haptic_get_effect_index_from_name_u(const unsigned char *haptic_buffer, const unsigned short *effect_name, int *effect_index) +{ + int status; + + if (device_handle_count == 0) { + ERR("Haptic device is not opened yet"); + return HAPTIC_NOT_OPENED; + } + + if (has_haptic_module == 0) { + ERR("%s() is not supported without specific haptic module", __func__); + return HAPTIC_NOT_SUPPORTED; + } + + return _haptic_internal_get_IVT_effect_index_from_name_u(haptic_buffer, effect_name, effect_index); +} + +EXTAPI +int device_haptic_play_effect(int device_handle, const unsigned char *haptic_buffer, int effect_index, int *effect_handle) +{ + int status; + + if (device_handle_count == 0) { + ERR("Haptic device is not opened yet"); + return HAPTIC_NOT_OPENED; + } + + if (has_haptic_module == 0) { + ERR("%s() is not supported without specific haptic module", __func__); + return HAPTIC_NOT_SUPPORTED; + } + + return _haptic_internal_play_IVT_effect(device_handle, haptic_buffer, effect_index, effect_handle); +} + +EXTAPI +int device_haptic_play_effect_repeat(int device_handle, const unsigned char *haptic_buffer, int effect_index, unsigned char repeat, int *effect_handle) +{ + int status; + + if (device_handle_count == 0) { + ERR("Haptic device is not opened yet"); + return HAPTIC_NOT_OPENED; + } + + if (has_haptic_module == 0) { + ERR("%s() is not supported without specific haptic module", __func__); + return HAPTIC_NOT_SUPPORTED; + } + + return _haptic_internal_play_IVT_effect_repeat(device_handle, haptic_buffer, effect_index, repeat, effect_handle); +} + +EXTAPI +int device_haptic_stop_playing_effect(int device_handle, int effect_handle) +{ + int status; + + if (device_handle_count == 0) { + ERR("Haptic device is not opened yet"); + return HAPTIC_NOT_OPENED; + } + + if (has_haptic_module == 0) { + ERR("%s() is not supported without specific haptic module", __func__); + return HAPTIC_NOT_SUPPORTED; + } + + return _haptic_internal_stop_playing_effect(device_handle, effect_handle); +} + +EXTAPI +int device_haptic_get_effect_type(const unsigned char *haptic_buffer, int effect_index, int *effect_type) +{ + int status; + + if (device_handle_count == 0) { + ERR("Haptic device is not opened yet"); + return HAPTIC_NOT_OPENED; + } + + if (has_haptic_module == 0) { + ERR("%s() is not supported without specific haptic module", __func__); + return HAPTIC_NOT_SUPPORTED; + } + + return _haptic_internal_get_IVT_effect_type(haptic_buffer, effect_index, effect_type); +} + +EXTAPI +int device_haptic_get_magsweep_effect_definition(const unsigned char *haptic_buffer, int effect_index, + int *duration, int *magnitude, int *style, int *attacktime, int *attacklevel, + int *fadetime, int *fadelevel) +{ + int status; + + if (device_handle_count == 0) { + ERR("Haptic device is not opened yet"); + return HAPTIC_NOT_OPENED; + } + + if (has_haptic_module == 0) { + ERR("%s() is not supported without specific haptic module", __func__); + return HAPTIC_NOT_SUPPORTED; + } + + return _haptic_internal_get_IVT_magsweep_effect_definition(haptic_buffer, effect_index, duration, magnitude, style, attacktime, attacklevel, fadetime, fadelevel); +} + +EXTAPI +int device_haptic_get_periodic_effect_definition(const unsigned char *haptic_buffer, int effect_index, + int *duration, int *magnitude, int *period, int *style_and_wave_type, int *attacktime, int *attacklevel, + int *fadetime, int *fadelevel) +{ + int status; + + if (device_handle_count == 0) { + ERR("Haptic device is not opened yet"); + return HAPTIC_NOT_OPENED; + } + + if (has_haptic_module == 0) { + ERR("%s() is not supported without specific haptic module", __func__); + return HAPTIC_NOT_SUPPORTED; + } + + return _haptic_internal_get_IVT_periodic_effect_definition(haptic_buffer, effect_index, duration, magnitude, period, style_and_wave_type, attacktime, attacklevel, fadetime, fadelevel); +} + +EXTAPI +int device_haptic_get_effect_duration(const unsigned char *haptic_buffer, int effect_index, int *effect_duration) +{ + int status; + + if (device_handle_count == 0) { + ERR("Haptic device is not opened yet"); + return HAPTIC_NOT_OPENED; + } + + if (has_haptic_module == 0) { + ERR("%s() is not supported without specific haptic module", __func__); + return HAPTIC_NOT_SUPPORTED; + } + + return _haptic_internal_get_IVT_effect_duration(haptic_buffer, effect_index, effect_duration); +} + +EXTAPI +int device_haptic_play_magsweep_effect(int device_handle, + int duration, int magnitude, int style, int attacktime, int attacklevel, + int fadetime, int fadelevel, int *effect_handle) +{ + int status; + + if (device_handle_count == 0) { + ERR("Haptic device is not opened yet"); + return HAPTIC_NOT_OPENED; + } + + if (has_haptic_module == 0) { + ERR("%s() is not supported without specific haptic module", __func__); + return HAPTIC_NOT_SUPPORTED; + } + + return _haptic_internal_play_magsweep_effect(device_handle, duration, magnitude, style, attacktime, attacklevel, fadetime, fadelevel, effect_handle); +} + +EXTAPI +int device_haptic_play_periodic_effect(int device_handle, + int duration, int magnitude, int period, int style_and_wave_type, int attacktime, int attacklevel, + int fadetime, int fadelevel, int *effect_handle) +{ + int status; + + if (device_handle_count == 0) { + ERR("Haptic device is not opened yet"); + return HAPTIC_NOT_OPENED; + } + + if (has_haptic_module == 0) { + ERR("%s() is not supported without specific haptic module", __func__); + return HAPTIC_NOT_SUPPORTED; + } + + return _haptic_internal_play_periodic_effect(device_handle, duration, magnitude, period, style_and_wave_type, attacktime, attacklevel, fadetime, fadelevel, effect_handle); +} + +EXTAPI +int device_haptic_modify_playing_magsweep_effect(int device_handle, int effect_handle, + int duration, int magnitude, int style, int attacktime, int attacklevel, int fadetime, int fadelevel) +{ + int status; + + if (device_handle_count == 0) { + ERR("Haptic device is not opened yet"); + return HAPTIC_NOT_OPENED; + } + + if (has_haptic_module == 0) { + ERR("%s() is not supported without specific haptic module", __func__); + return HAPTIC_NOT_SUPPORTED; + } + + return _haptic_internal_modify_playing_magsweep_effect(device_handle, effect_handle, duration, magnitude, style, attacktime, attacklevel, fadetime, fadelevel); +} + +EXTAPI +int device_haptic_modify_playing_periodic_effect(int device_handle, int effect_handle, + int duration, int magnitude, int period, int style_and_wave_type, int attacktime, int attacklevel, int fadetime, int fadelevel) +{ + int status; + + if (device_handle_count == 0) { + ERR("Haptic device is not opened yet"); + return HAPTIC_NOT_OPENED; + } + + if (has_haptic_module == 0) { + ERR("%s() is not supported without specific haptic module", __func__); + return HAPTIC_NOT_SUPPORTED; + } + + return _haptic_internal_modify_playing_periodic_effect(device_handle, effect_handle, duration, magnitude, period, style_and_wave_type, attacktime, attacklevel, fadetime, fadelevel); +} + +EXTAPI +int device_haptic_create_streaming_effect(int device_handle, int *effect_handle) +{ + int status; + + if (device_handle_count == 0) { + ERR("Haptic device is not opened yet"); + return HAPTIC_NOT_OPENED; + } + + if (has_haptic_module == 0) { + ERR("%s() is not supported without specific haptic module", __func__); + } + + return _haptic_internal_create_streaming_effect(device_handle, effect_handle); +} + +EXTAPI +int device_haptic_destroy_streaming_effect(int device_handle, int effect_handle) +{ + int status; + + if (device_handle_count == 0) { + ERR("Haptic device is not opened yet"); + return HAPTIC_NOT_OPENED; + } + + if (has_haptic_module == 0) { + ERR("%s() is not supported without specific haptic module", __func__); + return HAPTIC_NOT_SUPPORTED; + } + + return _haptic_internal_destroy_streaming_effect(device_handle, effect_handle); +} + +EXTAPI +int device_haptic_play_streaming_sample(int device_handle, int effect_handle, const unsigned char *streaming_sample, int size) +{ + int status; + + if (device_handle_count == 0) { + ERR("Haptic device is not opened yet"); + return HAPTIC_NOT_OPENED; + } + + if (has_haptic_module == 0) { + ERR("%s() is not supported without specific haptic module", __func__); + return HAPTIC_NOT_SUPPORTED; + } + + return _haptic_internal_play_streaming_sample(device_handle, effect_handle, streaming_sample, size); +} + +EXTAPI +int device_haptic_play_streaming_sample_with_offset(int device_handle, int effect_handle, const unsigned char *streaming_sample, int size, int offset_time) +{ + int status; + + if (device_handle_count == 0) { + ERR("Haptic device is not opened yet"); + return HAPTIC_NOT_OPENED; + } + + if (has_haptic_module == 0) { + ERR("%s() is not supported without specific haptic module", __func__); + return HAPTIC_NOT_SUPPORTED; + } + + return _haptic_internal_play_streaming_sample_with_offset(device_handle, effect_handle, streaming_sample, size, offset_time); +} + +EXTAPI +int device_haptic_stop_all_playing_effects(int device_handle) +{ + int status; + + if (device_handle_count == 0) { + ERR("Haptic device is not opened yet"); + return HAPTIC_NOT_OPENED; + } + + if (has_haptic_module == 0) { + ERR("%s() is not supported without specific haptic module", __func__); + return HAPTIC_NOT_SUPPORTED; + } + + return _haptic_internal_stop_all_playing_effects(device_handle); +} + +EXTAPI +int device_haptic_save_file(const unsigned char *haptic_buffer, const char *path_name) +{ + ERR("%s() is not supported without specific haptic module", __func__); + return -2; + + int status; + + if (device_handle_count == 0) { + ERR("Haptic device is not opened yet"); + return -1; + } + + if (has_haptic_module == 0) { + ERR("%s() is not supported without specific haptic module", __func__); + return -2; + } + + return _haptic_internal_save_IVT_file(haptic_buffer, path_name); +} + +EXTAPI +int device_haptic_delete_file(const char *path_name) +{ + int status; + + if (device_handle_count == 0) { + ERR("Haptic device is not opened yet"); + return HAPTIC_NOT_OPENED; + } + + if (has_haptic_module == 0) { + ERR("%s() is not supported without specific haptic module", __func__); + return HAPTIC_NOT_SUPPORTED; + } + + return _haptic_internal_delete_IVT_file(path_name); +} + +EXTAPI +int device_haptic_pause_playing_effect(int device_handle, int effect_handle) +{ + int status; + + if (device_handle_count == 0) { + ERR("Haptic device is not opened yet"); + return HAPTIC_NOT_OPENED; + } + + if (has_haptic_module == 0) { + ERR("%s() is not supported without specific haptic module", __func__); + return HAPTIC_NOT_SUPPORTED; + } + + return _haptic_internal_pause_playing_effect(device_handle, effect_handle); +} + +EXTAPI +int device_haptic_resume_paused_effect(int device_handle, int effect_handle) +{ + int status; + + if (device_handle_count == 0) { + ERR("Haptic device is not opened yet"); + return HAPTIC_NOT_OPENED; + } + + if (has_haptic_module == 0) { + ERR("%s() is not supported without specific haptic module", __func__); + return HAPTIC_NOT_SUPPORTED; + } + + return _haptic_internal_resume_paused_effect(device_handle, effect_handle); +} + +EXTAPI +int device_haptic_get_effect_state(int device_handle, int effect_handle, int *effect_state) +{ + int status; + + if (device_handle_count == 0) { + ERR("Haptic device is not opened yet"); + return HAPTIC_NOT_OPENED; + } + + if (has_haptic_module == 0) { + ERR("%s() is not supported without specific haptic module", __func__); + return HAPTIC_NOT_SUPPORTED; + } + + return _haptic_internal_get_effect_state(device_handle, effect_handle, effect_state); +} + +EXTAPI +int device_haptic_get_size(const unsigned char *haptic_buffer, int size) +{ + int status; + + if (device_handle_count == 0) { + ERR("Haptic device is not opened yet"); + return HAPTIC_NOT_OPENED; + } + + if (has_haptic_module == 0) { + ERR("%s() is not supported without specific haptic module", __func__); + return HAPTIC_NOT_SUPPORTED; + } + + return _haptic_internal_get_IVT_size(haptic_buffer, size); +} + +EXTAPI +int device_haptic_initialize_buffer(unsigned char *haptic_buffer, int size) +{ + int status; + + if (device_handle_count == 0) { + ERR("Haptic device is not opened yet"); + return HAPTIC_NOT_OPENED; + } + + if (has_haptic_module == 0) { + ERR("%s() is not supported without specific haptic module", __func__); + return HAPTIC_NOT_SUPPORTED; + } + + return _haptic_internal_initialize_IVT_buffer(haptic_buffer, size); +} + +EXTAPI +int device_haptic_insert_element(unsigned char *haptic_buffer, int size, int timeline_index, const HapticElement *element) +{ + int status; + + if (device_handle_count == 0) { + ERR("Haptic device is not opened yet"); + return HAPTIC_NOT_OPENED; + } + + if (has_haptic_module == 0) { + ERR("%s() is not supported without specific haptic module", __func__); + return HAPTIC_NOT_SUPPORTED; + } + + return _haptic_internal_insert_IVT_element(haptic_buffer, size, timeline_index, element); +} + +EXTAPI +int device_haptic_insert_element2(unsigned char *haptic_buffer, int size, int timeline_index, const HapticElement2 *element) +{ + int status; + + if (device_handle_count == 0) { + ERR("Haptic device is not opened yet"); + return HAPTIC_NOT_OPENED; + } + + if (has_haptic_module == 0) { + ERR("%s() is not supported without specific haptic module", __func__); + return HAPTIC_NOT_SUPPORTED; + } + + return _haptic_internal_insert_IVT_element2(haptic_buffer, size, timeline_index, element); +} + +EXTAPI +int device_haptic_insert_element3(unsigned char *haptic_buffer, int size, int timeline_index, const HapticElement3 *element) +{ + int status; + + if (device_handle_count == 0) { + ERR("Haptic device is not opened yet"); + return HAPTIC_NOT_OPENED; + } + + if (has_haptic_module == 0) { + ERR("%s() is not supported without specific haptic module", __func__); + return HAPTIC_NOT_SUPPORTED; + } + + return _haptic_internal_insert_IVT_element3(haptic_buffer, size, timeline_index, element); +} + +EXTAPI +int device_haptic_read_element(const unsigned char *haptic_buffer, int size, int timeline_index, int element_index, HapticElement *element) +{ + int status; + + if (device_handle_count == 0) { + ERR("Haptic device is not opened yet"); + return HAPTIC_NOT_OPENED; + } + + if (has_haptic_module == 0) { + ERR("%s() is not supported without specific haptic module", __func__); + return HAPTIC_NOT_SUPPORTED; + } + + return _haptic_internal_read_IVT_element(haptic_buffer, size, timeline_index, element_index, element); +} + +EXTAPI +int device_haptic_read_element2(const unsigned char *haptic_buffer, int size, int timeline_index, int element_index, HapticElement2 *element) +{ + int status; + + if (device_handle_count == 0) { + ERR("Haptic device is not opened yet"); + return HAPTIC_NOT_OPENED; + } + + if (has_haptic_module == 0) { + ERR("%s() is not supported without specific haptic module", __func__); + return HAPTIC_NOT_SUPPORTED; + } + + return _haptic_internal_read_IVT_element2(haptic_buffer, size, timeline_index, element_index, element); +} + +EXTAPI +int device_haptic_read_element3(const unsigned char *haptic_buffer, int size, int timeline_index, int element_index, HapticElement3 *element) +{ + int status; + + if (device_handle_count == 0) { + ERR("Haptic device is not opened yet"); + return HAPTIC_NOT_OPENED; + } + + if (has_haptic_module == 0) { + ERR("%s() is not supported without specific haptic module", __func__); + return HAPTIC_NOT_SUPPORTED; + } + + return _haptic_internal_read_IVT_element3(haptic_buffer, size, timeline_index, element_index, element); +} + +EXTAPI +int device_haptic_remove_element(unsigned char *haptic_buffer, int size, int timeline_index, int element_index) +{ + int status; + + if (device_handle_count == 0) { + ERR("Haptic device is not opened yet"); + return HAPTIC_NOT_OPENED; + } + + if (has_haptic_module == 0) { + ERR("%s() is not supported without specific haptic module", __func__); + return HAPTIC_NOT_SUPPORTED; + } + + return _haptic_internal_remove_IVT_element(haptic_buffer, size, timeline_index, element_index); +} +/* END: devman_haptic_ext APIs */ + +static void __attribute__ ((constructor)) module_init() +{ + char *error; + + if (access(HAPTIC_DEVICE_NODE_PATH, F_OK) < 0) { + has_haptic_module = 0; + return; + } else { + has_haptic_module = 1; + } + + dlopen_handle = dlopen(HAPTIC_MODULE_PATH, RTLD_LAZY); + if (!dlopen_handle) { + ERR("dlopen failed: %s", dlerror()); + has_haptic_module = 0; + return; + } + + _haptic_internal_play_buffer = dlsym(dlopen_handle, "_haptic_internal_play_buffer"); + if ((error = dlerror()) != NULL) { + ERR("dlsym failed : %s", error); + has_haptic_module = 0; + return; + } + + _haptic_internal_play_file = dlsym(dlopen_handle, "_haptic_internal_play_file"); + if ((error = dlerror()) != NULL) { + ERR("dlsym failed : %s", error); + has_haptic_module = 0; + return; + } + + _haptic_internal_play_monotone = dlsym(dlopen_handle, "_haptic_internal_play_monotone"); + if ((error = dlerror()) != NULL) { + ERR("dlsym failed : %s", error); + has_haptic_module = 0; + return; + } + + _haptic_internal_get_buffer_duration = dlsym(dlopen_handle, "_haptic_internal_get_buffer_duration"); + if ((error = dlerror()) != NULL) { + ERR("dlsym failed : %s", error); + has_haptic_module = 0; + return; + } + + _haptic_internal_get_file_duration = dlsym(dlopen_handle, "_haptic_internal_get_file_duration"); + if ((error = dlerror()) != NULL) { + ERR("dlsym failed : %s", error); + has_haptic_module = 0; + return; + } + + _haptic_internal_prepare_node = dlsym(dlopen_handle, "_haptic_internal_prepare_node"); + if ((error = dlerror()) != NULL) { + ERR("dlsym failed : %s", error); + has_haptic_module = 0; + return; + } + + _haptic_internal_initialize = dlsym(dlopen_handle, "_haptic_internal_initialize"); + if ((error = dlerror()) != NULL) { + ERR("dlsym failed : %s", error); + has_haptic_module = 0; + return; + } + + _haptic_internal_open_composite_device = dlsym(dlopen_handle, "_haptic_internal_open_composite_device"); + if ((error = dlerror()) != NULL) { + ERR("dlsym failed : %s", error); + has_haptic_module = 0; + return; + } + + _haptic_internal_open_device = dlsym(dlopen_handle, "_haptic_internal_open_device"); + if ((error = dlerror()) != NULL) { + ERR("dlsym failed : %s", error); + has_haptic_module = 0; + return; + } + + _haptic_internal_close_device = dlsym(dlopen_handle, "_haptic_internal_close_device"); + if ((error = dlerror()) != NULL) { + ERR("dlsym failed : %s", error); + has_haptic_module = 0; + return; + } + + _haptic_internal_terminate = dlsym(dlopen_handle, "_haptic_internal_terminate"); + if ((error = dlerror()) != NULL) { + ERR("dlsym failed : %s", error); + has_haptic_module = 0; + return; + } + + _haptic_internal_set_device_property_string = dlsym(dlopen_handle, "_haptic_internal_set_device_property_string"); + if ((error = dlerror()) != NULL) { + ERR("dlsym failed : %s", error); + has_haptic_module = 0; + return; + } + + _haptic_internal_set_device_property_int32 = dlsym(dlopen_handle, "_haptic_internal_set_device_property_int32"); + if ((error = dlerror()) != NULL) { + ERR("dlsym failed : %s", error); + has_haptic_module = 0; + return; + } + + + _haptic_internal_play_IVT_effect = dlsym(dlopen_handle, "_haptic_internal_play_IVT_effect"); + if ((error = dlerror()) != NULL) { + ERR("dlsym failed : %s", error); + has_haptic_module = 0; + return; + } + + _haptic_internal_play_IVT_effect_repeat = dlsym(dlopen_handle, "_haptic_internal_play_IVT_effect_repeat"); + if ((error = dlerror()) != NULL) { + ERR("dlsym failed : %s", error); + has_haptic_module = 0; + return; + } + + _haptic_internal_stop_all_playing_effects = dlsym(dlopen_handle, "_haptic_internal_stop_all_playing_effects"); + if ((error = dlerror()) != NULL) { + ERR("dlsym failed : %s", error); + has_haptic_module = 0; + return; + } + + + _haptic_internal_play_periodic_effect = dlsym(dlopen_handle, "_haptic_internal_play_periodic_effect"); + if ((error = dlerror()) != NULL) { + ERR("dlsym failed : %s", error); + has_haptic_module = 0; + return; + } + + _haptic_internal_get_device_count = dlsym(dlopen_handle, "_haptic_internal_get_device_count"); + if ((error = dlerror()) != NULL) { + ERR("dlsym failed : %s", error); + has_haptic_module = 0; + return; + } + + _haptic_internal_get_IVT_effect_duration = dlsym(dlopen_handle, "_haptic_internal_get_IVT_effect_duration"); + if ((error = dlerror()) != NULL) { + ERR("dlsym failed : %s", error); + has_haptic_module = 0; + return; + } + + _haptic_internal_play_magsweep_effect = dlsym(dlopen_handle, "_haptic_internal_play_magsweep_effect"); + if ((error = dlerror()) != NULL) { + ERR("dlsym failed : %s", error); + has_haptic_module = 0; + return; + } + + _haptic_internal_get_device_state = dlsym(dlopen_handle, "_haptic_internal_get_device_state"); + if ((error = dlerror()) != NULL) { + ERR("dlsym failed : %s", error); + has_haptic_module = 0; + return; + } + + _haptic_internal_get_device_property_bool = dlsym(dlopen_handle, "_haptic_internal_get_device_property_bool"); + if ((error = dlerror()) != NULL) { + ERR("dlsym failed : %s", error); + has_haptic_module = 0; + return; + } + + _haptic_internal_get_device_property_string = dlsym(dlopen_handle, "_haptic_internal_get_device_property_string"); + if ((error = dlerror()) != NULL) { + ERR("dlsym failed : %s", error); + has_haptic_module = 0; + return; + } + + _haptic_internal_get_device_property_int32 = dlsym(dlopen_handle, "_haptic_internal_get_device_property_int32"); + if ((error = dlerror()) != NULL) { + ERR("dlsym failed : %s", error); + has_haptic_module = 0; + return; + } + + _haptic_internal_set_device_property_bool = dlsym(dlopen_handle, "_haptic_internal_set_device_property_bool"); + if ((error = dlerror()) != NULL) { + ERR("dlsym failed : %s", error); + has_haptic_module = 0; + return; + } + + _haptic_internal_get_device_capability_bool = dlsym(dlopen_handle, "_haptic_internal_get_device_capability_bool"); + if ((error = dlerror()) != NULL) { + ERR("dlsym failed : %s", error); + has_haptic_module = 0; + return; + } + + _haptic_internal_get_device_capability_int32 = dlsym(dlopen_handle, "_haptic_internal_get_device_capability_int32"); + if ((error = dlerror()) != NULL) { + ERR("dlsym failed : %s", error); + has_haptic_module = 0; + return; + } + + _haptic_internal_get_device_capability_string = dlsym(dlopen_handle, "_haptic_internal_get_device_capability_string"); + if ((error = dlerror()) != NULL) { + ERR("dlsym failed : %s", error); + has_haptic_module = 0; + return; + } + + _haptic_internal_get_IVT_effect_count = dlsym(dlopen_handle, "_haptic_internal_get_IVT_effect_count"); + if ((error = dlerror()) != NULL) { + ERR("dlsym failed : %s", error); + has_haptic_module = 0; + return; + } + + _haptic_internal_get_IVT_effect_name = dlsym(dlopen_handle, "_haptic_internal_get_IVT_effect_name"); + if ((error = dlerror()) != NULL) { + ERR("dlsym failed : %s", error); + has_haptic_module = 0; + return; + } + + _haptic_internal_get_IVT_effect_name_u = dlsym(dlopen_handle, "_haptic_internal_get_IVT_effect_name_u"); + if ((error = dlerror()) != NULL) { + ERR("dlsym failed : %s", error); + has_haptic_module = 0; + return; + } + + _haptic_internal_get_IVT_effect_index_from_name = dlsym(dlopen_handle, "_haptic_internal_get_IVT_effect_index_from_name"); + if ((error = dlerror()) != NULL) { + ERR("dlsym failed : %s", error); + has_haptic_module = 0; + return; + } + + _haptic_internal_get_IVT_effect_index_from_name_u = dlsym(dlopen_handle, "_haptic_internal_get_IVT_effect_index_from_name_u"); + if ((error = dlerror()) != NULL) { + ERR("dlsym failed : %s", error); + has_haptic_module = 0; + return; + } + + _haptic_internal_get_IVT_effect_type = dlsym(dlopen_handle, "_haptic_internal_get_IVT_effect_type"); + if ((error = dlerror()) != NULL) { + ERR("dlsym failed : %s", error); + has_haptic_module = 0; + return; + } + + _haptic_internal_get_IVT_size = dlsym(dlopen_handle, "_haptic_internal_get_IVT_size"); + if ((error = dlerror()) != NULL) { + ERR("dlsym failed : %s", error); + has_haptic_module = 0; + return; + } + + _haptic_internal_get_IVT_magsweep_effect_definition = dlsym(dlopen_handle, "_haptic_internal_get_IVT_magsweep_effect_definition"); + if ((error = dlerror()) != NULL) { + ERR("dlsym failed : %s", error); + has_haptic_module = 0; + return; + } + + _haptic_internal_get_IVT_periodic_effect_definition = dlsym(dlopen_handle, "_haptic_internal_get_IVT_periodic_effect_definition"); + if ((error = dlerror()) != NULL) { + ERR("dlsym failed : %s", error); + has_haptic_module = 0; + return; + } + + _haptic_internal_modify_playing_magsweep_effect = dlsym(dlopen_handle, "_haptic_internal_modify_playing_magsweep_effect"); + if ((error = dlerror()) != NULL) { + ERR("dlsym failed : %s", error); + has_haptic_module = 0; + return; + } + + _haptic_internal_modify_playing_periodic_effect = dlsym(dlopen_handle, "_haptic_internal_modify_playing_periodic_effect"); + if ((error = dlerror()) != NULL) { + ERR("dlsym failed : %s", error); + has_haptic_module = 0; + return; + } + + _haptic_internal_create_streaming_effect = dlsym(dlopen_handle, "_haptic_internal_create_streaming_effect"); + if ((error = dlerror()) != NULL) { + ERR("dlsym failed : %s", error); + has_haptic_module = 0; + return; + } + + _haptic_internal_destroy_streaming_effect = dlsym(dlopen_handle, "_haptic_internal_destroy_streaming_effect"); + if ((error = dlerror()) != NULL) { + ERR("dlsym failed : %s", error); + has_haptic_module = 0; + return; + } + + _haptic_internal_play_streaming_sample = dlsym(dlopen_handle, "_haptic_internal_play_streaming_sample"); + if ((error = dlerror()) != NULL) { + ERR("dlsym failed : %s", error); + has_haptic_module = 0; + return; + } + + _haptic_internal_play_streaming_sample_with_offset = dlsym(dlopen_handle, "_haptic_internal_play_streaming_sample_with_offset"); + if ((error = dlerror()) != NULL) { + ERR("dlsym failed : %s", error); + has_haptic_module = 0; + return; + } + + _haptic_internal_save_IVT_file = dlsym(dlopen_handle, "_haptic_internal_save_IVT_file"); + if ((error = dlerror()) != NULL) { + ERR("dlsym failed : %s", error); + has_haptic_module = 0; + return; + } + + _haptic_internal_delete_IVT_file = dlsym(dlopen_handle, "_haptic_internal_delete_IVT_file"); + if ((error = dlerror()) != NULL) { + ERR("dlsym failed : %s", error); + has_haptic_module = 0; + return; + } + + _haptic_internal_stop_playing_effect = dlsym(dlopen_handle, "_haptic_internal_stop_playing_effect"); + if ((error = dlerror()) != NULL) { + ERR("dlsym failed : %s", error); + has_haptic_module = 0; + return; + } + + _haptic_internal_pause_playing_effect = dlsym(dlopen_handle, "_haptic_internal_pause_playing_effect"); + if ((error = dlerror()) != NULL) { + ERR("dlsym failed : %s", error); + has_haptic_module = 0; + return; + } + + _haptic_internal_resume_paused_effect = dlsym(dlopen_handle, "_haptic_internal_resume_paused_effect"); + if ((error = dlerror()) != NULL) { + ERR("dlsym failed : %s", error); + has_haptic_module = 0; + return; + } + + _haptic_internal_get_effect_state = dlsym(dlopen_handle, "_haptic_internal_get_effect_state"); + if ((error = dlerror()) != NULL) { + ERR("dlsym failed : %s", error); + has_haptic_module = 0; + return; + } + + _haptic_internal_initialize_IVT_buffer = dlsym(dlopen_handle, "_haptic_internal_initialize_IVT_buffer"); + if ((error = dlerror()) != NULL) { + ERR("dlsym failed : %s", error); + has_haptic_module = 0; + return; + } + + _haptic_internal_insert_IVT_element = dlsym(dlopen_handle, "_haptic_internal_insert_IVT_element"); + if ((error = dlerror()) != NULL) { + ERR("dlsym failed : %s", error); + has_haptic_module = 0; + return; + } + + _haptic_internal_insert_IVT_element2 = dlsym(dlopen_handle, "_haptic_internal_insert_IVT_element2"); + if ((error = dlerror()) != NULL) { + ERR("dlsym failed : %s", error); + has_haptic_module = 0; + return; + } + + _haptic_internal_insert_IVT_element3 = dlsym(dlopen_handle, "_haptic_internal_insert_IVT_element3"); + if ((error = dlerror()) != NULL) { + ERR("dlsym failed : %s", error); + has_haptic_module = 0; + return; + } + + _haptic_internal_read_IVT_element = dlsym(dlopen_handle, "_haptic_internal_read_IVT_element"); + if ((error = dlerror()) != NULL) { + ERR("dlsym failed : %s", error); + has_haptic_module = 0; + return; + } + + _haptic_internal_read_IVT_element2 = dlsym(dlopen_handle, "_haptic_internal_read_IVT_element2"); + if ((error = dlerror()) != NULL) { + ERR("dlsym failed : %s", error); + has_haptic_module = 0; + return; + } + + _haptic_internal_read_IVT_element3 = dlsym(dlopen_handle, "_haptic_internal_read_IVT_element3"); + if ((error = dlerror()) != NULL) { + ERR("dlsym failed : %s", error); + has_haptic_module = 0; + return; + } + + _haptic_internal_remove_IVT_element = dlsym(dlopen_handle, "_haptic_internal_remove_IVT_element"); + if ((error = dlerror()) != NULL) { + ERR("dlsym failed : %s", error); + has_haptic_module = 0; + return; + } +} + +static void __attribute__ ((destructor)) module_fini() +{ + if (dlopen_handle) { + dlclose(dlopen_handle); + } +} + diff --git a/device_haptic.h b/device_haptic.h new file mode 100644 index 0000000..f399421 --- /dev/null +++ b/device_haptic.h @@ -0,0 +1,65 @@ +/* + * devman + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: DongGi Jang + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * +*/ + + +#ifndef __DEVICE_HAPTIC_H__ +#define __DEVICE_HAPTIC_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Default capability value + */ +#define DEFAULT_MOTOR_COUNT 1 + +/* + * Default device handle + */ +#define DEFAULT_DEVICE_HANDLE 1 + +/* + * Motor property for generic APIs + */ + enum { + HAPTIC_PROP_ENABLE, + HAPTIC_PROP_LEVEL, + HAPTIC_PROP_LEVEL_MAX, + HAPTIC_PROP_VALUE, + HAPTIC_PROP_ONESHOT, + }; + +/* + * Feedback level for generic APIs + */ + enum { + VIBE_FEEDBACK_LEVEL_1 = 55, /* HAPTIC_FEEDBACK_LEVEL_1 */ + VIBE_FEEDBACK_LEVEL_2 = 60, /* HAPTIC_FEEDBACK_LEVEL_2 */ + VIBE_FEEDBACK_LEVEL_3 = 65, /* HAPTIC_FEEDBACK_LEVEL_3 */ + VIBE_FEEDBACK_LEVEL_4 = 70, /* HAPTIC_FEEDBACK_LEVEL_4 */ + VIBE_FEEDBACK_LEVEL_5 = 80, /* HAPTIC_FEEDBACK_LEVEL_5 */ + }; + +#ifdef __cplusplus +} +#endif +#endif diff --git a/device_haptic_tsp4000_pattern.h b/device_haptic_tsp4000_pattern.h new file mode 100644 index 0000000..7a7f253 --- /dev/null +++ b/device_haptic_tsp4000_pattern.h @@ -0,0 +1,125 @@ +/* + * devman + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: DongGi Jang + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * +*/ + + +#ifndef __DEVICE_HAPTIC_TSP4000_PATTERN_H__ +#define __DEVICE_HAPTIC_TSP4000_PATTERN_H__ + +#include "devman_haptic_ext.h" + +///////////////// +// for Beat UX // + +unsigned char touch_ivt[] = +{ + 0x01, 0x00, 0x01, 0x00, 0x0A, 0x00, 0x14, 0x00, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00, 0x7F, 0x00, + 0x00, 0x42, 0x00, 0x00, 0x4D, 0x00, 0x61, 0x00, 0x67, 0x00, 0x53, 0x00, 0x77, 0x00, 0x65, 0x00, + 0x65, 0x00, 0x70, 0x00, 0x00, 0x00 + +}; + +unsigned char hw_touch_ivt[] = +{ + 0x01, 0x00, 0x01, 0x00, 0x0A, 0x00, 0x14, 0x00, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00, 0x7F, 0x00, + 0x00, 0xE2, 0x00, 0x00, 0x4D, 0x00, 0x61, 0x00, 0x67, 0x00, 0x53, 0x00, 0x77, 0x00, 0x65, 0x00, + 0x65, 0x00, 0x70, 0x00, 0x00, 0x00 + +}; + +unsigned char noti_ivt[] = +{ + 0x01, 0x00, 0x02, 0x00, 0x1E, 0x00, 0x2E, 0x00, 0x00, 0x00, 0x12, 0x00, 0xF1, 0xE0, 0x01, 0xE2, + 0x00, 0x00, 0xF1, 0xE0, 0x01, 0xE2, 0x05, 0xDC, 0xD0, 0x07, 0xD0, 0xD1, 0x00, 0xFF, 0x20, 0x5D, + 0x00, 0x00, 0x7F, 0x00, 0x00, 0xC1, 0x00, 0x00, 0x12, 0x00, 0x54, 0x00, 0x69, 0x00, 0x6D, 0x00, + 0x65, 0x00, 0x6C, 0x00, 0x69, 0x00, 0x6E, 0x00, 0x65, 0x00, 0x00, 0x00, 0x4D, 0x00, 0x61, 0x00, + 0x67, 0x00, 0x53, 0x00, 0x77, 0x00, 0x65, 0x00, 0x65, 0x00, 0x70, 0x00, 0x20, 0x00, 0x23, 0x00, + 0x32, 0x00, 0x00, 0x00 + +}; + +unsigned char incomming_01_ivt[] = +{ + 0x01, 0x00, 0x02, 0x00, 0x34, 0x00, 0x34, 0x00, 0x00, 0x00, 0x27, 0x00, 0xF1, 0xE0, 0x01, 0xE2, + 0x00, 0x00, 0xD0, 0x01, 0x2C, 0xF1, 0xE0, 0x01, 0xE2, 0x01, 0x66, 0xD0, 0x07, 0xD0, 0xF1, 0xE0, + 0x01, 0xE2, 0x09, 0x84, 0xD0, 0x01, 0x2C, 0xF1, 0xE0, 0x01, 0xE2, 0x09, 0xC4, 0xD0, 0x01, 0xF4, + 0xD1, 0x00, 0xFF, 0x20, 0x7D, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x18, 0x00, + 0x4D, 0x00, 0x61, 0x00, 0x6E, 0x00, 0x6E, 0x00, 0x65, 0x00, 0x72, 0x00, 0x4D, 0x00, 0x6F, 0x00, + 0x64, 0x00, 0x65, 0x00, 0x36, 0x00, 0x00, 0x00, 0x4D, 0x00, 0x61, 0x00, 0x67, 0x00, 0x53, 0x00, + 0x77, 0x00, 0x65, 0x00, 0x65, 0x00, 0x70, 0x00, 0x20, 0x00, 0x23, 0x00, 0x32, 0x00, 0x00, 0x00 + +}; + +unsigned char incomming_02_ivt[] = +{ + 0x01, 0x00, 0x03, 0x00, 0x72, 0x00, 0x42, 0x00, 0x00, 0x00, 0x54, 0x00, 0x64, 0x00, 0xF1, 0xE0, + 0x02, 0xE2, 0x00, 0x00, 0xF1, 0xE0, 0x01, 0xE2, 0x00, 0x00, 0xF1, 0xE0, 0x02, 0xE2, 0x01, 0xAE, + 0xF1, 0xE0, 0x02, 0xE2, 0x02, 0xCC, 0xF1, 0xE0, 0x02, 0xE2, 0x03, 0xAA, 0xF1, 0xE0, 0x02, 0xE2, + 0x04, 0x5B, 0xF1, 0xE0, 0x02, 0xE2, 0x04, 0xFE, 0xF1, 0xE0, 0x02, 0xE2, 0x05, 0x8C, 0xF1, 0xE0, + 0x02, 0xE2, 0x06, 0x0C, 0xF1, 0xE0, 0x02, 0xE2, 0x06, 0x8C, 0xF1, 0xE0, 0x02, 0xE2, 0x07, 0x05, + 0xF1, 0xE0, 0x02, 0xE2, 0x07, 0x6A, 0xF1, 0xE0, 0x02, 0xE2, 0x0A, 0xF0, 0xD0, 0x00, 0xC8, 0xD1, + 0x00, 0xFF, 0x30, 0xB3, 0x09, 0x00, 0x00, 0x00, 0x7F, 0x00, 0x20, 0xB5, 0x00, 0x00, 0x7F, 0x00, + 0x00, 0x40, 0x20, 0x06, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x42, 0x00, 0x00, 0x12, 0x00, 0x24, 0x00, + 0x54, 0x00, 0x69, 0x00, 0x6D, 0x00, 0x65, 0x00, 0x6C, 0x00, 0x69, 0x00, 0x6E, 0x00, 0x65, 0x00, + 0x00, 0x00, 0x4D, 0x00, 0x61, 0x00, 0x67, 0x00, 0x53, 0x00, 0x77, 0x00, 0x65, 0x00, 0x65, 0x00, + 0x70, 0x00, 0x00, 0x00, 0x4D, 0x00, 0x61, 0x00, 0x67, 0x00, 0x53, 0x00, 0x77, 0x00, 0x65, 0x00, + 0x65, 0x00, 0x70, 0x00, 0x20, 0x00, 0x23, 0x00, 0x31, 0x00, 0x00, 0x00 + +}; + +unsigned char incomming_03_ivt[] = +{ + 0x01, 0x00, 0x03, 0x00, 0x34, 0x00, 0x42, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x26, 0x00, 0xF1, 0xE0, + 0x02, 0xE2, 0x00, 0x00, 0xD0, 0x03, 0x31, 0xF1, 0xE0, 0x01, 0xE2, 0x03, 0x76, 0xD0, 0x05, 0xAE, + 0xF1, 0xE0, 0x01, 0xE2, 0x0A, 0xF0, 0xD0, 0x00, 0xC8, 0xD1, 0x00, 0xFF, 0x20, 0x06, 0x00, 0x00, + 0x7F, 0x00, 0x00, 0x41, 0x20, 0x3E, 0x00, 0x00, 0x7F, 0x81, 0x3E, 0x82, 0x00, 0x00, 0x18, 0x00, + 0x2A, 0x00, 0x54, 0x00, 0x69, 0x00, 0x6D, 0x00, 0x65, 0x00, 0x6C, 0x00, 0x69, 0x00, 0x6E, 0x00, + 0x65, 0x00, 0x20, 0x00, 0x23, 0x00, 0x32, 0x00, 0x00, 0x00, 0x4D, 0x00, 0x61, 0x00, 0x67, 0x00, + 0x53, 0x00, 0x77, 0x00, 0x65, 0x00, 0x65, 0x00, 0x70, 0x00, 0x00, 0x00, 0x50, 0x00, 0x65, 0x00, + 0x72, 0x00, 0x69, 0x00, 0x6F, 0x00, 0x64, 0x00, 0x69, 0x00, 0x63, 0x00, 0x00, 0x00 + +}; + +unsigned char alerts_call_ivt[] = +{ + 0x01, 0x00, 0x01, 0x00, 0x0A, 0x00, 0x14, 0x00, 0x00, 0x00, 0x20, 0x06, 0x00, 0x00, 0x19, 0x00, + 0x00, 0x40, 0x00, 0x00, 0x4D, 0x00, 0x61, 0x00, 0x67, 0x00, 0x53, 0x00, 0x77, 0x00, 0x65, 0x00, + 0x65, 0x00, 0x70, 0x00, 0x00, 0x00 + +}; + +unsigned char operation_ivt[] = +{ + 0x01, 0x00, 0x01, 0x00, 0x0A, 0x00, 0x1A, 0x00, 0x00, 0x00, 0x20, 0x06, 0x00, 0x00, 0x7F, 0x00, + 0x00, 0x41, 0x00, 0x00, 0x4D, 0x00, 0x61, 0x00, 0x67, 0x00, 0x53, 0x00, 0x77, 0x00, 0x65, 0x00, + 0x65, 0x00, 0x70, 0x00, 0x20, 0x00, 0x23, 0x00, 0x32, 0x00, 0x00, 0x00 + +}; + +unsigned char silent_ivt[] = +{ + 0x01, 0x00, 0x01, 0x00, 0x12, 0x00, 0x14, 0x00, 0x00, 0x00, 0x30, 0x96, 0x00, 0x96, 0x00, 0x00, + 0x00, 0x00, 0x20, 0x1F, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x41, 0x00, 0x00, 0x4D, 0x00, 0x61, 0x00, + 0x67, 0x00, 0x53, 0x00, 0x77, 0x00, 0x65, 0x00, 0x65, 0x00, 0x70, 0x00, 0x00, 0x00 + +}; + + +#endif /* __DEVICE_HAPTIC_TSP4000_PATTERN_H__ */ diff --git a/device_path.h b/device_path.h new file mode 100644 index 0000000..8f7502d --- /dev/null +++ b/device_path.h @@ -0,0 +1,42 @@ +/* + * devman + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: DongGi Jang + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * +*/ + + +#ifndef _DEVICE_PATH_H_ +#define _DEVICE_PATH_H_ + +/* DEVICE SYSFS PATH */ +#define CLASS_HAPTIC "/sys/class/haptic" +#define SYS_DEVICE_JACK "/sys/devices/platform/jack" +#define CLASS_POWERSUPPLY "/sys/class/power_supply" +#define CLASS_BACKLIGHT "/sys/class/backlight" +#define CLASS_LCD "/sys/class/lcd" +#define CLASS_LED "/sys/class/leds" +#define CLASS_TOUCHKEY "/sys/class/input/event3" + +/* Device reference path */ +#define REF_FILE_HAPTIC "/tmp/haptic" +#define REF_FILE_POWERSUPPLY "/tmp/powersupply" +#define REF_FILE_LCD "/tmp/lcd" +#define REF_FILE_BACKLIGHT "/tmp/backlight" +#define REF_FILE_TOUCHKEY "/tmp/touchkey" + +#endif diff --git a/devices/CMakeLists.txt b/devices/CMakeLists.txt new file mode 100644 index 0000000..6c041f9 --- /dev/null +++ b/devices/CMakeLists.txt @@ -0,0 +1,12 @@ +SET(TARGET_SRCS + devices/haptic.c + devices/jack_35pi.c + devices/jack_microusb.c + devices/mmc.c + devices/power_supply_battery.c + devices/power_supply_pmic.c + devices/uart.c + devices/video.c + devices/led.c +) + diff --git a/devices/haptic.c b/devices/haptic.c new file mode 100644 index 0000000..e1c072f --- /dev/null +++ b/devices/haptic.c @@ -0,0 +1,63 @@ +/* + * devman + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: DongGi Jang + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * +*/ + + +#include "device_engine.h" +#include "device_generic.h" +#include "device_haptic.h" + +#define NODE_NAME "vibetones" + +static int get_haptic(int prop, int *val) +{ + switch (prop) { + case HAPTIC_PROP_LEVEL: + case HAPTIC_PROP_LEVEL_MAX: + case HAPTIC_PROP_VALUE: + return generic_class_haptic_get(NODE_NAME, prop, val); + } + + return -1; +} + +static int set_haptic(int prop, int val) +{ + switch (prop) { + case HAPTIC_PROP_ENABLE: + case HAPTIC_PROP_LEVEL: + case HAPTIC_PROP_ONESHOT: + return generic_class_haptic_set(NODE_NAME, prop, val); + } + + return -1; +} + +static struct device haptic = { + .devname = "haptic", + .set_int = set_haptic, + .get_int = get_haptic, + .devtype = DEVTYPE_HAPTIC +}; + +static void __attribute__ ((constructor)) module_init() +{ + add_dev(&haptic); +} diff --git a/devices/jack_35pi.c b/devices/jack_35pi.c new file mode 100644 index 0000000..11af66f --- /dev/null +++ b/devices/jack_35pi.c @@ -0,0 +1,83 @@ +/* + * devman + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: DongGi Jang + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * +*/ + + +#include "device_engine.h" +#include "device_path.h" +#include "device_generic.h" + +enum snd_jack_types { + SND_JACK_HEADPHONE = 0x0001, + SND_JACK_MICROPHONE = 0x0002, + SND_JACK_HEADSET = SND_JACK_HEADPHONE | SND_JACK_MICROPHONE, + SND_JACK_LINEOUT = 0x0004, + SND_JACK_MECHANICAL = 0x0008, + SND_JACK_VIDEOOUT = 0x0010, + SND_JACK_AVOUT = SND_JACK_LINEOUT | SND_JACK_VIDEOOUT, +}; + +static int get_35pi(int prop, int *val) +{ + + switch (prop) { + case JACK_PROP_MIC_ONLINE: + return -1; + case JACK_PROP_EARKEY_PRESS: + return sys_get_int(SYS_DEVICE_JACK "/earkey_online", val); + + case JACK_PROP_EARJACK_ONLINE: + case JACK_PROP_TVOUT_ONLINE: + generic_jack_interface_get(NULL, JACK_PROP_EARJACK_ONLINE, val); + + printf("val : %d\n", *val); + + if (prop == JACK_PROP_EARJACK_ONLINE) { + if ((*val | ~SND_JACK_HEADPHONE) == 0xFFFFFFFF || + ((*val | ~SND_JACK_HEADSET) == 0xFFFFFFFF)) + *val = 1; + else + *val = 0; + + return 0; + } else { + if (*val == SND_JACK_MECHANICAL + || *val == SND_JACK_AVOUT) + *val = 1; + else + *val = 0; + + return 0; + } + } + + return -1; +} + +static struct device microusb = { + .devname = "35pi", + .get_int = get_35pi, + .devtype = DEVTYPE_JACK, +}; + +static void __attribute__ ((constructor)) module_init() +{ + add_dev(µusb); +} diff --git a/devices/jack_microusb.c b/devices/jack_microusb.c new file mode 100644 index 0000000..77109f7 --- /dev/null +++ b/devices/jack_microusb.c @@ -0,0 +1,134 @@ +/* + * devman + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: DongGi Jang + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * +*/ + + +#include +#include +#include +#include +#include +#include "device_engine.h" +#include "device_generic.h" + +#define USB_PATH_SYSFS "/sys/devices/platform/usb-switch/path" +#define MODEM_REGULATOR_SYSFS "/sys/class/regulator/regulator.29/state" + +enum { + PATH_TO_MODEM = 0, + PATH_TO_PDA, +}; + +static const char *usb_path_string[3] = { "CP\0", "AP\0" }; + +static int get_microusb_status(int prop, int *val) +{ + char *tmp_buff = NULL; + switch (prop) { + case JACK_PROP_USB_ONLINE: + case JACK_PROP_TA_ONLINE: + return generic_jack_interface_get(NULL, prop, val); + + case JACK_PROP_HDMI_ONLINE: + tmp_buff = + sys_get_str("/sys/class/i2c-adapter/i2c-5/5-0072/status"); + if (tmp_buff && (strstr(tmp_buff, "MHL connected:yes") != 0)) { + free(tmp_buff); + *val = 1; + } else { + if(tmp_buff) + free(tmp_buff); + *val = 0; + } + return 0; + case JACK_PROP_USB_PATH: + tmp_buff = sys_get_str(USB_PATH_SYSFS); + if (tmp_buff == NULL) + return -1; + if (strncmp(tmp_buff, usb_path_string[PATH_TO_MODEM], 2) == 0) + *val = PATH_TO_MODEM; + else + *val = PATH_TO_PDA; + + free(tmp_buff); + return 0; + } + + free(tmp_buff); + return -1; +} + +static int set_microusb_path(int prop, int val) +{ + char *cur_path; + int conn; + + switch (prop) { + case JACK_PROP_USB_PATH: + break; + default: + return -1; + } + cur_path = sys_get_str(USB_PATH_SYSFS); + if (cur_path == NULL) + return -1; + + switch (val) { + case PATH_TO_MODEM: + case PATH_TO_PDA: + if (strncmp(cur_path, usb_path_string[val], 2) == 0) { + free(cur_path); + return 0; + } + free(cur_path); + if (generic_jack_interface_get + (NULL, JACK_PROP_USB_ONLINE, &conn) != 0) { + /*failed to get the connection status */ + return -1; + } + if (sys_set_str(USB_PATH_SYSFS, (char *)usb_path_string[val]) != + 0) + return -1; + if (val == PATH_TO_MODEM) { + system("/usr/bin/save_blenv usbpath CP"); + } else { + system("/usr/bin/save_blenv usbpath AP"); + } + break; + + default: + free(cur_path); + return -1; + } + + return 0; +} + +static struct device microusb = { + .devname = "microusb", + .set_int = set_microusb_path, + .get_int = get_microusb_status, + .devtype = DEVTYPE_JACK, +}; + +static void __attribute__ ((constructor)) module_init() +{ + add_dev(µusb); +} diff --git a/devices/led.c b/devices/led.c new file mode 100644 index 0000000..061e906 --- /dev/null +++ b/devices/led.c @@ -0,0 +1,68 @@ +/* + * devman + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: DongGi Jang + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * +*/ + + +#include +#include +#include + +#include "devlog.h" +#include "device_engine.h" +#include "device_generic.h" +#include "device_path.h" + +#define SYSFS_LED "/sys/class/led" +#define NODE_NAME "leds-torch" + +static char node_name[PATH_MAX]; +static char bl_node_name[PATH_MAX]; + +static int get_led_prop(int prop, int *val) +{ + char *gamma; + switch (prop) { + case LED_PROP_BRIGHTNESS: + case LED_PROP_MAX_BRIGHTNESS: + return generic_class_led_get(NODE_NAME, prop, val); + } + return -1; +} + +static int set_led_prop(int prop, int val) +{ + switch (prop) { + case LED_PROP_BRIGHTNESS: + return generic_class_led_set(NODE_NAME, prop, val); + } + return -1; +} + +static struct device led_prop = { + .devname = "led", + .set_int = set_led_prop, + .get_int = get_led_prop, + .devtype = DEVTYPE_LED +}; + +static void __attribute__ ((constructor)) module_init() +{ + add_dev(&led_prop); +} diff --git a/devices/mmc.c b/devices/mmc.c new file mode 100644 index 0000000..0ae517d --- /dev/null +++ b/devices/mmc.c @@ -0,0 +1,233 @@ +/* + * devman + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: DongGi Jang + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * +*/ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "devlog.h" +#include "device_engine.h" +#include "device_path.h" +#include +#include + +#define MMC_DEV "/dev/mmcblk" +#define MMC_MOUNT_PATH "/opt/storage/sdcard" + + +static int exec_process(char *name, const char *arg1) +{ + int ret, pid; + int i; + + if (name[0] == '\0') + return 0; + + pid = fork(); + switch (pid) { + case -1: + ERR("Fork error"); + ret = -1; + break; + case 0: + for (i = 0; i < _NSIG; i++) + signal(i, SIG_DFL); + execl(name, name, arg1, NULL); + ERR("execlp() error : %s\n", strerror(errno)); + exit(-1); + break; + default: + ret = pid; + break; + } + return ret; +} + +static int get_mmcblk_num() +{ + int i; + char buf[255]; + + /* mmcblk0 and mmcblk1 is reserved for movinand */ + for (i = 9; i > 0; i--) { + snprintf(buf, 255, "%s%d", MMC_DEV, i); + if (access(buf, R_OK) == 0) + return i; + } + ERR("Failed to find mmc block number\n"); + return -1; +} + +int format_mmc(int blknum) +{ + int fd; + struct stat parent_stat, mount_stat; + + /* check MMC_MOUNT_FULL_PATH length */ + char parent_path[PATH_MAX], mount_path[PATH_MAX]; + int ret_f = 0, ret_s = 0; + char buf[512]; + char dev_mmcblk[NAME_MAX]; + int mkfs_pid = 0; + + if (blknum < 0) { + vconf_set_int("memory/mmc/format", 2); + vconf_set_int(VCONFKEY_SYSMAN_MMC_FORMAT, + VCONFKEY_SYSMAN_MMC_FORMAT_FAILED); + return -1; + } else + snprintf(dev_mmcblk, NAME_MAX, "%s%d", MMC_DEV, blknum); + + snprintf(parent_path, sizeof(parent_path), "%s/%s", MMC_MOUNT_PATH, ".."); + snprintf(mount_path, sizeof(mount_path), "%s", MMC_MOUNT_PATH); + + if (stat(mount_path, &mount_stat) != 0) { + ERR("get stat error : %s\n", mount_path); + ret_f = -1; + } else if (stat(parent_path, &parent_stat) != 0) { + ERR("get stat error : %s\n", parent_path); + ret_f = -1; + } + + else if (mount_stat.st_dev == parent_stat.st_dev) { + ERR("Does not mounted, same st_dev\n"); + ret_f = -2; + } else { + ERR("MMC mounted, diff st_dev\n"); + } + + if (ret_f == 0) { + if (umount2(MMC_MOUNT_PATH, MNT_FORCE) == -1) { + ERR("devman mmc_format umount fail\n"); + if (umount2(MMC_MOUNT_PATH, MNT_FORCE) == -1) { + vconf_set_int("memory/mmc/format", 2); + vconf_set_int(VCONFKEY_SYSMAN_MMC_FORMAT, + VCONFKEY_SYSMAN_MMC_FORMAT_FAILED); + ERR("devman mmc_format umount retry fail\n"); + return -1; + } + } + } + + fd = open(dev_mmcblk, O_RDWR); + if (fd < 0) { + ERR("%s open fail", dev_mmcblk); + ret_s = -1; + } else { + + memset(buf, 0, sizeof(buf)); + if (write(fd, buf, sizeof(buf)) < 0) { + ERR("%s write fail to erase partition\n", dev_mmcblk); + close(fd); + ret_s = -2; + } else { + sync(); + usleep(200000); + + if (ioctl(fd, BLKRRPART, NULL) < 0) { + ERR("%s ioctl fail\n", dev_mmcblk); + close(fd); + ret_s = -3; + } else { + close(fd); + sync(); + + mkfs_pid = + exec_process("/sbin/mkfs.vfat", dev_mmcblk); + if (mkfs_pid == -1) { + ERR("devman mmc_format mkfs.vfat fail\n"); + ret_s = -4; + } + } + } + } + int i = 0; + snprintf(buf, sizeof(buf), "%s%d", "/proc/", mkfs_pid); + while (1) { + sleep(1); + if (access(buf, R_OK) != 0) + break; + } + sync(); + + if (ret_f == 0 && ret_s == 0) { + if (mount + (dev_mmcblk, MMC_MOUNT_PATH, "vfat", 0, + "uid=0,gid=0,dmask=0000,fmask=0111,iocharset=iso8859-1,utf8,shortname=mixed") + != 0) { + ERR("Failed to mount mmc card, %s,%s\n", dev_mmcblk, + MMC_MOUNT_PATH); + vconf_set_int("memory/mmc/format", 2); + vconf_set_int(VCONFKEY_SYSMAN_MMC_FORMAT, + VCONFKEY_SYSMAN_MMC_FORMAT_FAILED); + heynoti_publish("mmcblk_remove"); + return -1; + } else + if (heynoti_publish("mmcblk_add") == -1 + && ret_s == 0) + ERR("notification failed for new MMC\n"); + } else { + vconf_set_int("memory/mmc/format", 2); + vconf_set_int(VCONFKEY_SYSMAN_MMC_FORMAT, + VCONFKEY_SYSMAN_MMC_FORMAT_FAILED); + ERR("result format process fail\n"); + heynoti_publish("mmcblk_remove"); + return -1; + } + + vconf_set_int("memory/mmc/format", 0); + vconf_set_int(VCONFKEY_SYSMAN_MMC_FORMAT, + VCONFKEY_SYSMAN_MMC_FORMAT_COMPLETED); + return 0; +} + +static int set_mmc_int(int prop, int val) +{ + int ret = -1; + switch (prop) { + case MMC_PROP_FORMAT: + ret = format_mmc(get_mmcblk_num()); + return ret; + } + + return -1; + +} + +static struct device mmc = { + .devname = "mmc", + .set_int = set_mmc_int, + .devtype = DEVTYPE_MMC, +}; + +static void __attribute__ ((constructor)) module_init() +{ + add_dev(&mmc); +} diff --git a/devices/power_supply_battery.c b/devices/power_supply_battery.c new file mode 100644 index 0000000..0d80b33 --- /dev/null +++ b/devices/power_supply_battery.c @@ -0,0 +1,48 @@ +/* + * devman + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: DongGi Jang + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * +*/ + + +#include "device_engine.h" +#include "device_generic.h" + +#define NODE_NAME "battery" + +static int get_battery(int prop, int *val) +{ + switch (prop) { + case POWER_SUPPLY_PROP_CAPACITY: + return generic_class_power_supply_get(NODE_NAME, prop, val); + } + + return -1; +} + +static struct device powersupply = { + .devname = "power_supply_battery", + .set_int = NULL, + .get_int = get_battery, + .devtype = DEVTYPE_POWERSUPPLY, +}; + +static void __attribute__ ((constructor)) module_init() +{ + add_dev(&powersupply); +} diff --git a/devices/power_supply_pmic.c b/devices/power_supply_pmic.c new file mode 100644 index 0000000..845b627 --- /dev/null +++ b/devices/power_supply_pmic.c @@ -0,0 +1,49 @@ +/* + * devman + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: DongGi Jang + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * +*/ + + +#include "device_engine.h" +#include "device_generic.h" + +#define NODE_NAME "battery" + +static int get_pmic(int prop, int *val) +{ + switch (prop) { + case POWER_SUPPLY_PROP_CHARGE_NOW: + case POWER_SUPPLY_PROP_CHARGE_FULL: + return generic_class_power_supply_get(NODE_NAME, prop, val); + } + + return -1; +} + +static struct device powersupply = { + .devname = "power_supply_pmic", + .set_int = NULL, + .get_int = get_pmic, + .devtype = DEVTYPE_POWERSUPPLY, +}; + +static void __attribute__ ((constructor)) module_init() +{ + add_dev(&powersupply); +} diff --git a/devices/uart.c b/devices/uart.c new file mode 100644 index 0000000..16ad7a2 --- /dev/null +++ b/devices/uart.c @@ -0,0 +1,96 @@ +/* + * devman + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: DongGi Jang + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * +*/ + + +#include +#include +#include +#include "devlog.h" +#include "device_engine.h" +#include "device_path.h" + +#define SYS_DEVICE_UART_PATH "/sys/devices/platform/uart-select/path" + +enum { + PATH_TO_MODEM = 0, + PATH_TO_PDA, +}; + +static int uart_get(int prop, int *val) +{ + char *tmp_buff; + switch (prop) { + case UART_PROP_SELECT_PATH: + tmp_buff = sys_get_str(SYS_DEVICE_UART_PATH); + if (tmp_buff == NULL) + return -1; + + if (strncmp(tmp_buff, "AP", 2) == 0) { + *val = PATH_TO_PDA; + } else if (strncmp(tmp_buff, "CP", 2) == 0) { + *val = PATH_TO_MODEM; + } else { + free(tmp_buff); + return -1; + } + free(tmp_buff); + break; + } + + return 0; +} + +static int uart_set(int prop, int val) +{ + int ret = -1; + + switch (prop) { + case UART_PROP_SELECT_PATH: + if (val < PATH_TO_MODEM || val > PATH_TO_PDA) { + return -1; + } + ret = + sys_set_str(SYS_DEVICE_UART_PATH, + (val == PATH_TO_MODEM) ? "CP" : "AP"); + if(ret == 0) { + if (val == PATH_TO_MODEM) { + system("/usr/bin/save_blenv uartpath CP"); + } else { + system("/usr/bin/save_blenv uartpath AP"); + } + } + return ret; + } + + return -1; +} + +static struct device uart = { + .devname = "uart", + .set_int = uart_set, + .get_int = uart_get, + .devtype = DEVTYPE_UART, +}; + +static void __attribute__ ((constructor)) module_init() +{ + add_dev(&uart); +} diff --git a/devices/video.c b/devices/video.c new file mode 100644 index 0000000..7ddf2ad --- /dev/null +++ b/devices/video.c @@ -0,0 +1,180 @@ +/* + * devman + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: DongGi Jang + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * +*/ + + +#include +#include +#include + +#include "devlog.h" +#include "device_engine.h" +#include "device_generic.h" +#include "device_path.h" + +#define SYSFS_LCD "/sys/class/lcd" +#define SYSFS_GAMMA "/sys/bus/spi/devices/spi2.0/gamma_mode" +#define SYSFS_mDNIe_PATH "/sys/devices/platform/s3cfb/mdnie_path" + +static char node_name[PATH_MAX]; +static char bl_node_name[PATH_MAX]; + +static int get_display_count(int *val) +{ + DIR *root_dir; + struct dirent *entry; + + int r, count = 0; + + root_dir = opendir(SYSFS_LCD); + + if (root_dir == NULL) { + ERR("Failed to open directory: %s", SYSFS_LCD); + return -1; + } + + if (val == NULL) { + ERR("Argument is null pointer"); + closedir(root_dir); + return -1; + } + + while ((entry = readdir(root_dir)) != NULL) { + if (strncmp(entry->d_name, ".", 1) == 0 + || strncmp(entry->d_name, "..", 2) == 0) + continue; + ++count; + } + + if (count <= 0) { + ERR("Failed to get number of display nodes"); + r = closedir(root_dir); + if (r < 0) + ERR("Failed to close directory"); + return -1; + } + *val = count; + + r = closedir(root_dir); + if (r < 0) + ERR("Failed to close directory"); + + return 0; +} + +static bool is_enable_mDNIe(void) +{ + char *mdnie_path; + mdnie_path = sys_get_str(SYSFS_mDNIe_PATH); + + if (mdnie_path == NULL) + return false; + + if (strncmp("mDNIe", mdnie_path, 5) == 0) { + free(mdnie_path); + return true; + } + + free(mdnie_path); + return false; +} + +static int search_node(void) +{ + int ret; + ret = find_sysfs_node(CLASS_LCD, node_name); + if (ret < 0) { + DBG("lcd node not found"); + return -1; + } + + ret = find_sysfs_node(CLASS_BACKLIGHT, bl_node_name); + if (ret < 0) { + DBG("backlight node not found"); + return -1; + } + + DBG("*** %s, %s ***", node_name, bl_node_name); + return 0; +} + +static int get_video_prop(int prop, int *val) +{ + int ret = search_node(); + if (ret != 0) { + DBG("find node fail"); + return -1; + } + + char *gamma; + switch (prop) { + case DISPLAY_PROP_BRIGHTNESS: + case DISPLAY_PROP_MAX_BRIGHTNESS: + return generic_class_backlight_get(bl_node_name, prop, val); + case DISPLAY_PROP_ONOFF: + if (generic_class_lcd_get(node_name, prop, val) != 0) + return -1; + *val = !(*val); + return 0; + case DISPLAY_PROP_GAMMA: + /* not supported yet */ + return 0; + case DISPLAY_PROP_DISPLAY_COUNT: + if (get_display_count(val) < 0) + return -1; + return 0; + } + return -1; +} + +static int set_video_prop(int prop, int val) +{ + int ret = search_node(); + if (ret != 0) { + DBG("find node fail"); + return -1; + } + switch (prop) { + case DISPLAY_PROP_BRIGHTNESS: + return generic_class_backlight_set(bl_node_name, prop, val); + case DISPLAY_PROP_ONOFF: + if (val == 0) + val = 4; + else + val = 0; + return generic_class_lcd_set(node_name, prop, val); + case DISPLAY_PROP_GAMMA: + /* not supported yet */ + return 0; + } + return -1; +} + +static struct device video_prop = { + .devname = "video", + .set_int = set_video_prop, + .get_int = get_video_prop, + .devtype = DEVTYPE_DISPLAY0 +}; + +static void __attribute__ ((constructor)) module_init() +{ + add_dev(&video_prop); +} diff --git a/devlog.h b/devlog.h new file mode 100644 index 0000000..a96779c --- /dev/null +++ b/devlog.h @@ -0,0 +1,177 @@ +/* + * devman + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: DongGi Jang + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * +*/ + + +#ifndef __DEVLOG_H__ +#define __DEVLOG_H__ + +/* + * SYSLOG_INFO(), SYSLOG_ERR(), SYSLOG_DBG() are syslog() wrappers. + * PRT_INFO(), PRT_ERR(), PRT_DBG() are fprintf() wrappers. + * + * If SLP_DEBUG is not defined, SYSLOG_DBG() and PRT_DBG() is ignored. + * + * IF SLP_SYSLOG_OUT is defined, + * INFO(), ERR(), DBG() are SYSLOG_XXX() + * IF ENABLE_DLOG_OUT is defined, + * INFO(), ERR(), DBG() are SLOGI(), SLOGE(), SLOGD() + * Otherwise, + * They are PRT_XXX() + * + * + * warn_if(exrp, fmt, ...) + * If expr is true, The fmt string is printed using ERR(). + * + * ret_if(), retv_if(), retm_if(), retvm_if() + * If expr is true, current function return. + * Postfix 'v' means that it has a return value and 'm' means that it has output message. + * + */ +#include +#include + +#if defined(ENABLE_DLOG_OUT) +# define LOG_TAG "DEVMAN" +# include +#else +# include +# define __LOG(prio, fmt, arg...) \ + do { syslog(prio, fmt, ##arg); } while (0) +# define __LOGD(prio, fmt, arg...) \ + do { \ + if (getenv("SLP_DEBUG")) { \ + syslog(prio, "[%s:%d] "fmt"\n", __FILE__, __LINE__, ##arg); \ + } \ + } while (0) +#endif + +#define __PRTI(fmt, arg...) \ + do { fprintf(stdout, fmt"\n", ##arg); } while (0) +#define __PRTE(fmt, arg...) \ + do { fprintf(stderr, fmt"\n", ##arg); } while (0) +#define __PRTD(fmt, arg...) \ + do { \ + if (getenv("SLP_DEBUG")) { \ + fprintf(stdout, "[%s:%d] "fmt"\n", __FILE__, __LINE__, ##arg); \ + } \ + } while(0) +#define _NOUT(arg...) do { } while (0) + +#ifdef SLP_DEBUG +# define _LOGD __LOGD +# define _LOG __LOG +# define _PRTD __PRTD +# define _PRTI __PRTI +# define _PRTE __PRTE +#else +# define _LOGD _NOUT +# define _LOG __LOG +# define _PRTD _NOUT +# define _PRTI __PRTI +# define _PRTE __PRTE +#endif + +#define PRT_INFO(fmt, arg...) _PRTI(fmt, ##arg) +#define PRT_ERR(fmt, arg...) _PRTE(fmt, ##arg) +#define PRT_DBG(fmt, arg...) _PRTD(fmt, ##arg) + +#if defined(SLP_SYSLOG_OUT) +# define SYSLOG_INFO(fmt, arg...) _LOG(LOG_INFO, fmt, ##arg) +# define SYSLOG_ERR(fmt, arg...) _LOG(LOG_ERR, fmt, ##arg) +# define SYSLOG_DBG(fmt, arg...) _LOGD(LOG_DEBUG, fmt, ##arg) +# define INFO SYSLOG_INFO +# define ERR SYSLOG_ERR +# define DBG SYSLOG_DBG +#elif defined(ENABLE_DLOG_OUT) +# define INFO SLOGI +# define ERR SLOGE +# define DBG SLOGD +#else +# define INFO PRT_INFO +# define ERR PRT_ERR +# define DBG PRT_DBG +#endif + +#ifdef SLP_DEBUG +# define warn_if(expr, fmt, arg...) do { \ + if (expr) { \ + DBG("(%s) -> "fmt, #expr, ##arg); \ + } \ + } while (0) +# define ret_if(expr) do { \ + if (expr) { \ + DBG("(%s) -> %s() return", #expr, __FUNCTION__); \ + return; \ + } \ + } while (0) +# define retv_if(expr, val) do { \ + if (expr) { \ + DBG("(%s) -> %s() return", #expr, __FUNCTION__); \ + return (val); \ + } \ + } while (0) +# define retm_if(expr, fmt, arg...) do { \ + if (expr) { \ + ERR(fmt, ##arg); \ + DBG("(%s) -> %s() return", #expr, __FUNCTION__); \ + return; \ + } \ + } while (0) +# define retvm_if(expr, val, fmt, arg...) do { \ + if (expr) { \ + ERR(fmt, ##arg); \ + DBG("(%s) -> %s() return", #expr, __FUNCTION__); \ + return (val); \ + } \ + } while (0) + +#else +# define warn_if(expr, fmt, arg...) do { \ + if (expr) { \ + ERR(fmt, ##arg); \ + } \ + } while (0) +# define ret_if(expr) do { \ + if (expr) { \ + return; \ + } \ + } while (0) +# define retv_if(expr, val) do { \ + if (expr) { \ + return (val); \ + } \ + } while (0) +# define retm_if(expr, fmt, arg...) do { \ + if (expr) { \ + ERR(fmt, ##arg); \ + return; \ + } \ + } while (0) +# define retvm_if(expr, val, fmt, arg...) do { \ + if (expr) { \ + ERR(fmt, ##arg); \ + return (val); \ + } \ + } while (0) + +#endif + +#endif /* __DEVLOG_H__ */ diff --git a/devman b/devman new file mode 100755 index 0000000..74d324b --- /dev/null +++ b/devman @@ -0,0 +1,35 @@ +#!/bin/sh + +do_start () { + # If setting for device is needed, do here +} + +## for setting default brightness +set_display () { + BL_BRT= + for file in /sys/class/backlight/*; do + # echo $file + if [ -e $file ]; then + BL_BRT=$file/brightness + break + fi + done + /bin/echo `/usr/bin/vconftool get db/setting/Brightness | /usr/bin/awk '{print $4}'` > $BL_BRT + /bin/echo 0 > /sys/class/leds/leds-torch/brightness +} + +case "$1" in + start) + do_start + ;; + display) + set_display + ;; + *) + echo "Usage: $0 start | display" + exit 1 + +esac + +exit 0 + diff --git a/devman.h b/devman.h new file mode 100644 index 0000000..9e2fbed --- /dev/null +++ b/devman.h @@ -0,0 +1,474 @@ +/* + * devman + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: DongGi Jang + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * +*/ + + +#ifndef __DEVMAN_H__ +#define __DEVMAN_H__ + +#ifndef DEPRECATED +#define DEPRECATED __attribute__((deprecated)) +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @file devman.h + * @ingroup DEVICE_MANAGER + * @brief This file contains the API for the status of devices + * @author SLP2.0 + * @date 2010-01-24 + * @version 0.1 + */ + +/** + * @defgroup DEVICE_MANAGER Device Manager + * @ingroup SYSTEM_FRAMEWORK + * @brief Device Manager library + * + * Device manager provides APIs to control devices or to get the status of devices. + *
Use devman.pc and include devman.h and devman_haptic.h files + * + * @addtogroup DEVICE_MANAGER + * @{ + */ + +/** + * @par Description: + * device type enum + */ + typedef enum devtype_list { + DEVTYPE_POWERSUPPLY, /**< battery, PMIC, etc about power */ + DEVTYPE_DISPLAY0, /**< main screen */ + DEVTYPE_DISPLAY1, /**< sub screen */ + DEVTYPE_HAPTIC, /**< motor */ + DEVTYPE_LED, /**< LED */ + DEVTYPE_JACK, /**< jack - Micro USB, 3.5 pi jack etc */ + DEVTYPE_TOUCHSCREEN, /**< main touch screen */ + DEVTYPE_TOUCHKEY, /**< touchkey */ + DEVTYPE_GPS, + DEVTYPE_UART, + DEVTYPE_MMC, /**< MMC card(Micro SD) */ + DEVTYPE_EFFECT_HAPTIC, /**< extended touchsense */ + + DEVTYPE_MAX + } devtype_t; + +/** + * @par Description: + * DEVTYPE_POWERSUPPLY property for generic APIs + */ + enum { + POWER_SUPPLY_PROP_CHARGE_FULL, + /**< Battery is full-charged.*/ + POWER_SUPPLY_PROP_CHARGE_NOW, + /**< Battery is being charged now */ + POWER_SUPPLY_PROP_CAPACITY, /**< Current remaining battery */ + }; + +/** + * @par Description: + * DEVTYPE_DISPLAY0 and DEVTYPE_DISPLAY1 property for generic APIs + */ + enum { + DISPLAY_PROP_ONOFF, + DISPLAY_PROP_BRIGHTNESS, + DISPLAY_PROP_MAX_BRIGHTNESS, + DISPLAY_PROP_GAMMA, + DISPLAY_PROP_DISPLAY_COUNT, + }; + +/** + * @par Description: + * DEVTYPE_LED property for generic APIs + */ + enum { + LED_PROP_BRIGHTNESS, + LED_PROP_MAX_BRIGHTNESS, + }; + +/** + * @par Description: + * DEVTYPE_JACK property for generic APIs + */ + enum { + JACK_PROP_EARJACK_ONLINE, + /**< Earjack */ + JACK_PROP_MIC_ONLINE, /**< Microphone */ + JACK_PROP_TVOUT_ONLINE, /**< analog tvout */ + JACK_PROP_USB_ONLINE, /**< USB connection */ + JACK_PROP_TA_ONLINE, /**< Travel Adapter(Charger) */ + JACK_PROP_HDMI_ONLINE, /**< Digital tvout */ + JACK_PROP_USB_PATH, /**< */ + JACK_PROP_EARKEY_PRESS, /**< */ + JACK_PROP_CRADLE_ONLINE,/**< Cradle connection */ + }; + +/** + * @par Description: + * DEVTYPE_TOUCHKEY property for generic APIs + */ + enum { + TCKEY_PROP_FIRST, + /**< */ + TCKEY_PROP_SECOND, + /**< */ + TCKEY_PROP_THIRD, + /**< */ + }; + +/** + * @par Description: + * DEVTYPE_UART property for generic APIs + */ + enum { + UART_PROP_SELECT_PATH, + }; + +/** + * @par Description: + * DEVTYPE_MMC property for generic APIs + */ + enum { + MMC_PROP_FORMAT, + }; + +/** + * @fn int device_get_property(devtype_t devtype, int property, int *value) + * @par Description: + * This generic API is used to get the property values of supported devices.\n + * If the caller process does not have permission, it returns failure. + * @param[in] devtype device type that you want to get the value + * @param[in] property value property that you want to get the value + * @param[out] *value current value of device property + * @return 0 on success, -1 if failed + * @see device_set_property() + * @par Example: + * @code + * ... + * if( device_get_property(DEVTYPE_POWERSUPPLY, POWER_SUPPLY_PROP_CAPACITY, &val) < 0 ) + * printf("Fail to get property\n"); + * else + * printf("Property is %d\n", val); + * ... + * @endcode + */ + int device_get_property(devtype_t devtype, int property, int *value); + +/** + * @fn int device_set_property(devtype_t devtype, int property, int value) + * @par Description: + * This generic API is used to set the property values of supported devices.\n + * If the caller process does not have permission, it returns failure. + * @param[in] devtype device type that you want to set the value + * @param[in] property value property that you want to set the value + * @param[in] value value that you want to set + * @return 0 on success, -1 if failed + * @see device_get_property() + * @par Example + * @code + * ... + * if( device_set_property(DEVTYPE_DISPLAY0, DISPLAY_PROP_BRIGHTNESS, val) < 0 ) + * printf("Fail to set property\n"); + * else + * printf("Property is set %d\n", val); + * ... + * @endcode + */ + int device_set_property(devtype_t devtype, int property, int value); + +/* Application level interfaces */ + +/** + * @par Description: + * This API is used to get the remaining battery percentage.\n + * It gets the Battery percentage by calling device_get_property() function.\n + * It returns integer value(0~100) that indicate remaining batterty percentage on success.\n + * Or a negative value(-1) is returned on failure. + * @return On success, integer value(0~100) is returned. + * Or a negative value(-1) is returned on failure. + * @see device_is_battery_full() + * @par Example + * @code + * ... + * int battery; + * battery = device_get_battery_pct(); + * if( battery < 0 ) + * printf("Fail to get the remaining battery percentage.\n"); + * else + * printf("remaining battery percentage : %d\n", battery); + * ... + * @endcode + */ + int device_get_battery_pct(void); + +/** + * @par Description: + * This API is used to get the fully charged status of battery.\n + * It gets the fully charged status of Battery by calling device_get_property() function.\n + * If the status of battery is full, it returns 1.\n + * Or a negative value(-1) is returned, if the status of battery is not full. + * @return 1 with battery full, or 0 on not full-charged, -1 if failed + * @see device_get_battery_pct() + * @par Example + * @code + * ... + * if ( device_is_battery_full() > 0 ) + * printf("battery fully chared\n"); + * ... + * @endcode + */ + int device_is_battery_full(void); + +/** + * @par Description: + * Display number + */ + typedef enum { + DEV_DISPLAY_0, /**< */ + DEV_DISPLAY_1, /**< */ + DEV_MAIN_DISPLAY = DEV_DISPLAY_0, /**< */ + } display_num_t; + +/** + * @par Description: + * This API is used to get the current brightness of the display.\n + * It gets the current brightness of the display by calling device_get_property() function.\n + * It returns integer value which is the current brightness on success.\n + * Or a negative value(-1) is returned on failure. + * @param[in] num display number that you want to get the brightness value + * @return current brightness value on success, -1 if failed + * @see device_set_diplay_brt() + * @par Example + * @code + * ... + * int cur_brt; + * cur_brt = device_get_display_brt(0); + * if( cur_brt < 0 ) + * printf("Fail to get the current brightness of the display.\n"); + * else + * printf("Current brightness of the display is %d\n", cur_brt); + * ... + * @endcode + */ + int device_get_display_brt(display_num_t num); + +/** + * @par Description: + * This API is used to set the current brightness of the display.\n + * It sets the current brightness of the display by calling device_set_property() function.\n + * MUST use this API very carefully. \n + * you MUST set original brightness by device_release_brt_ctrl(), + * after you finish your job using this API. + * @param[in] num display number that you want to set the brightness value + * @param[in] val brightness value that you want to set + * @return 0 on success, -1 if failed + * @see device_get_diplay_brt(), device_release_brt_ctrl() + * @par Example + * @code + * ... + * if( device_set_display_brt(0,6) < 0 ) + * printf("Fail to set the current brightness of the display0\n"); + * else + * printf("The current brightness of the display0 is set 6\n"); + * ... + * @endcode + */ + int device_set_display_brt(display_num_t num, int val); + +/** + * @par Description: + * This API is used to release brightness control.\n + * It sets the current brightness of the display by calling device_set_property() function.\n + * MUST call this API after you finished the job which need to change the brightness. + * @param[in] num display number + * @return 0 on success, -1 if failed + * @see device_set_display_brt() + * @par Example + * @code + * ... + * org_val = device_get_display_brt(0); + * device_set_display_brt(0,1); + * ... + * ret = device_release_brt_ctrl(0); + * if( ret < 0 ) + * printf("Fail to release brightness control\n"); + * ... + * @endcode + */ + int device_release_brt_ctrl(display_num_t num); + +/** + * @par Description: + * This API is used to get the max brightness of the display.\n + * It gets the current brightness of the display by calling device_get_property() function.\n + * It returns integer value which is the max brightness on success.\n + * Or a negative value(-1) is returned on failure + * @param[in] num display number + * @return max brightness value on success, -1 if failed + * @par Example + * @code + * ... + * int max_brt; + * max_brt = device_get_max_brt(0); + * if( max_brt < 0 ) + * printf("Fail to get the max brightness of the display.\n"); + * else + * printf("Max brightness of the display is %d\n", max_brt); + * ... + * @endcode + */ + int device_get_max_brt(display_num_t num); + +/** + * @par Description: + * LCD gamma values + */ + typedef enum { + LCD_GAMMA_22 = 1, /**< 8500K , 2.2 GAMMA*/ + LCD_GAMMA_19 = 2, /**< 8500K , 1.9 GAMMA*/ + LCD_GAMMA_17 = 3, /**< 8500K , 1.7 GAMMA*/ + LCD_GAMMA_NORMAL = LCD_GAMMA_22, /**< Normal screen */ + LCD_GAMMA_PLAY_RECORD = LCD_GAMMA_19, /**< Playing or recording cam */ + LCD_GAMMA_PREVIEW = LCD_GAMMA_17, /**< Preview */ + LCD_GAMMA_MOVIE = LCD_GAMMA_19, /**< Movie */ + LCD_GAMMA_CAMERA = 11, /**< Camera */ + } display_gamma_t; + +/** + * @par Description: + * This API is used to get the current gamma of the display.\n + * It gets the current gamma of the display by calling device_get_property() function.\n + * It returns enum value which is the current gamma on success.\n + * Or a negative value(-1) is returned on failure. + * @param[in] num display number that you want to get the gamma value + * @return current gamma enum value on success, -1 if failed + * @see device_set_diplay_gamma() + * @par Example + * @code + * ... + * int cur_brt; + * cur_brt = device_get_display_gamma(0); + * if( cur_brt < 0 ) + * printf("Fail to get the current gamma of the display.\n"); + * else + * printf("Current gamma of the display is %d\n", cer_brt); + * ... + * @endcode + */ + int device_get_display_gamma(display_num_t num); + +/** + * @par Description: + * This API is used to set the specific gamma value of the display .\n + * It sets the specific gamma value of the display by calling device_set_property() function.\n + * MUST use this API very carefully. \n + * you MUST set original gamma by device_release_gamma_ctrl(), + * after you finish your job using this API. + * @param[in] num display number that you want to set the gamma value + * @param[in] new_val lcd gamma enum value that you want to set + * @return 0 on success, -1 if failed + * @see device_get_diplay_gammat(), device_release_gamma_ctrl() + * @par Example + * @code + * ... + * if( device_set_display_gamma(0,1) < 0 ) + * printf("Fail to set the specific gamma of the display0\n"); + * else + * printf("The gamma of the display0 is set 1(LCD_GAMMA_22)\n"); + * ... + * @endcode + */ + int device_set_display_gamma(display_num_t num, + display_gamma_t new_val); + +/** + * @par Description: + * This API is used to release gamma control.\n + * It sets the gamma of the display by calling device_set_property() function.\n + * MUST call this API after you finished the job which need to change the gamma. + * @param[in] num display number + * @param[in] org_val original gamma enums value before you control the gamma + * @return 0 on success, -1 if failed + * @see device_set_display_gamma() + * @par Example + * @code + * ... + * org_val = device_get_display_gamma(0); + * device_set_display_gamma(0,2); + * ... + * ret = device_release_gamma_ctrl(0, org_val); + * if( ret < 0 ) + * printf("Fail to release gamma control\n"); + * ... + * @endcode + */ + int device_release_gamma_ctrl(display_num_t num, + display_gamma_t org_val); + +/** + * @par Description: + * This API is used to get number of displays on the phone.\n + * It gets the current number of displays by calling device_get_display_count() function.\n + * It returns enum value which is the current number on success.\n + * Or a negative value(-1) is returned on failure. + * @return 0 on success, -1 if failed + * @par Example + * @code + * ... + * ret = device_get_display_count(); + * if( ret < 0 ) + * printf("Fail to get number of displays\n"); + * ... + * @endcode + */ + int device_get_display_count(void); + +/** + * @par Description: + * This API is used to make the phone go to a suspend (sleep) state. \n + * The suspend state consumes little battery power. \n + * If the caller process does not have permission, it returns failure. + * @return 0 on success, -1 if failed + * @par Example + * @code + * ... + * ret = device_power_suspend(); + * if( ret < 0 ) + * printf("Fail to make the phone go to a suspend (sleep) state\n"); + * ... + * @endcode + */ + int device_power_suspend(void); + + int device_get_led_brt(void); + int device_set_led_brt(int val); + int device_get_max_led(void); + +/** + * @} // end of internal APIs + */ + +#ifdef __cplusplus +} +#endif +#endif diff --git a/devman.pc.in b/devman.pc.in new file mode 100644 index 0000000..fa263eb --- /dev/null +++ b/devman.pc.in @@ -0,0 +1,13 @@ +# Package Information for pkg-config + +prefix=@PREFIX@ +exec_prefix=@EXEC_PREFIX@ +libdir=@LIBDIR@ +includedir=@INCLUDEDIR@ + +Name: device manager +Description: SLP device control library +Version: @VERSION@ +Requires: +Libs: -L${libdir} -ldevman -ldl +Cflags: -I${includedir} diff --git a/devman_haptic.h b/devman_haptic.h new file mode 100644 index 0000000..d41d9f8 --- /dev/null +++ b/devman_haptic.h @@ -0,0 +1,391 @@ +/* + * devman + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: DongGi Jang + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * +*/ + + +#ifndef __DEVMAN_HAPTIC_H__ +#define __DEVMAN_HAPTIC_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @file devman_haptic.h + * @ingroup DEVICE_MANAGER + * @brief This file contains the prototypes of the haptic API + * @author SLP2.0 + * @date 2010-01-24 + * @version 0.1 + */ + +/** + * @addtogroup DEVICE_MANAGER + * @{ + */ + + +/** + * @par Description: + * The pattern list for haptic.\n + * Note: The patterns will be removed except the patterns which are used for BEAT UX after 9. Dec. 2011. + */ + enum effectvibe_pattern_list { + EFFCTVIBE_TOUCH = 0, /**< for BeatUX */ + EFFCTVIBE_HW_TOUCH, /**< for BeatUX */ + EFFCTVIBE_NOTIFICATION, /**< for BeatUX */ + EFFCTVIBE_INCOMING_CALL01, /**< for BeatUX */ + EFFCTVIBE_INCOMING_CALL02, /**< for BeatUX */ + EFFCTVIBE_INCOMING_CALL03, /**< for BeatUX */ + EFFCTVIBE_ALERTS_CALL, /**< for BeatUX */ + EFFCTVIBE_OPERATION, /**< for BeatUX */ + EFFCTVIBE_SILENT_MODE, /**< for BeatUX */ + + EFFCTVIBE_PATTERN_END + }; + +/** + * @par Description: + * feedback level for haptic. + */ + enum haptic_feedback_level { + HAPTIC_FEEDBACK_LEVEL_AUTO = -1, /**< auto feedback level */ + HAPTIC_FEEDBACK_LEVEL_1 = 1, /**< feedback level 1 */ + HAPTIC_FEEDBACK_LEVEL_2 = 2, /**< feedback level 2 */ + HAPTIC_FEEDBACK_LEVEL_3 = 3, /**< feedback level 3 */ + HAPTIC_FEEDBACK_LEVEL_4 = 4, /**< feedback level 4 */ + HAPTIC_FEEDBACK_LEVEL_5 = 5, /**< feedback level 5 */ + }; + +/** + * @par Description: + * infinite iteration count + */ +#define HAPTIC_INFINITE_ITERATION 256 + +/** + * @par Description: + * Return Values + */ +#define HAPTIC_SUCCESS 0 +#define HAPTIC_NOT_OPENED -2 +#define HAPTIC_FAIL -4 +#define HAPTIC_NOT_SUPPORTED -13 + +/** + * @par Description: + * Motor device index. We support two motors now. + */ + typedef enum haptic_dev_idx_t { + DEV_IDX_0 = 0x01, /**< 1st motor */ + DEV_IDX_1 = 0x02, /**< 2nd motor */ + DEV_IDX_ALL = 0x04, /**< both of them */ + } haptic_dev_idx; + +/** + * @fn int device_haptic_open(haptic_dev_idx dev_idx, unsigned int mode) + * @par Description: + * This API opens a Haptic-vibration device. \n + * On success it returns a dev_handle value. In case of failure it returns a negative value. \n + * If the device is already open it returns (-1).\n + * The first in parameter dev_idx should be from a predefined haptic-device-index which is available in the typedef enum haptic_dev_idx.\n + * The DEV_IDX_0 means first haptic-device-index of target , the DEV_IDX_1 means second haptic-device-index of target \n + * and the DEV_IDX_ALL means both of them. \n + * The availability of the dev_idx value is dependent on the real target. Normally, set a DEV_IDX_0 value to the first haptic-device.\n + * The second in parameter mode is reserved for future so just set a 0 value\n + * Note: The device_haptic_open() must be called before all other haptic APIs are called. \n + * The device_haptic_open() should have a matching call to device_haptic_close().\n + * Applications call the device_haptic_open() only once if possible during application startup and call the device_haptic_close() during application shutdown. + * @param[in] dev_idx set a device index (predefined enum value by haptic_dev_idx) + * @param[in] mode just set a "0" value (not support current , reserved for future) + * @return if it succeed, it return dev_handle value , otherwise negative value return + * @see device_haptic_close() + * @par Example: + * @code + * ... + * int ret_val=0; + * int dev_handle; + * + * //Open the haptic device + * dev_handle = device_haptic_open(DEV_IDX_0,0); + * if(dev_handle < 0) + * return -1; + * ... + * @endcode + */ + + int device_haptic_open(haptic_dev_idx dev_idx, unsigned int mode); + +/** + * @fn int device_haptic_close(int dev_handle) + * @par Description: + * This API closes a Haptic-vibration device. \n + * On success it returns a zero value. In case of failure it returns a negative value. \n + * If the device is already closed it returns (-1). \n + * The first in parameter dev_handle should be from the return value of device_haptic_open(). + * hatic device close + * @param[in] dev_handle set recived dev_handle value from device_haptic_open() + * @return if it succeed, it return zero value , otherwise negative value return + * @see device_haptic_open() + * @par Example: + * @code + * ... + * //Close the device + * ret_val = device_haptic_close(dev_handle); + * if(ret_val != 0) + * return -1 + * ... + * @endcode + */ + + int device_haptic_close(int dev_handle); + +/** + * @fn int device_haptic_play_pattern(int dev_handle, int pattern , int iteration , int feedback_level ) + * @par Description: + * This API plays a predefined rhythmic haptic-vibration pattern. \n + * The first in parameter dev_handle should be from the return value of device_haptic_open().\n + * The second in parameter pattern should be from a predefined pattern list which is available in an enumeration (effectvibe_pattern_list). + * These patterns are rhythmic vibration patterns. \n + * The third in parameter iteration sets the number of iterations to be played. + * This should be less than the maximum iteration range set for the device (currently its 255). \n + * The fourth in parameter is the vibration feedback intensity level. + * This level is already predefined by enumeration type value from HAPTIC_FEEDBACK_LEVEL_1 to HAPTIC_FEEDBACK_LEVEL_5. + * If you want to use the value selected by the user in the Setting application menu, just set -1 value.\n + * On success it returns a zero value. In case of failure it returns a negative value. \n + * Note: The actual behavior of the feedback play pattern and the intensity depends on the target hardware. + * @param[in] dev_handle set recived dev_handle value from device_haptic_open() + * @param[in] pattern set predefined pattern enum value from effectvibe_pattern_list + * @param[in] iteration set iteration count + * @param[in] feedback_level set feed_back level value ( it is dependent on target's hardware ) + * @return if it succeed, it return zero value , otherwise negative value return + * @see device_haptic_play_file(), device_haptic_play_monoton(), device_haptic_stop_play() + * @par Example + * @code + * ... + * //Play a rhythmic pattern + * ret_val = device_haptic_play_pattern(dev_handle, EFFCTVIBE_POPUP, HAPTIC_TEST_ITERATION , HAPTIC_FEEDBACK_LEVEL_3); + * if(ret_val !=0) + * return -1; + * ... + * @endcode + */ + + int device_haptic_play_pattern(int dev_handle, int pattern, + int iteration, int feedback_level); + +/** + * @fn int device_haptic_play_file(int dev_handle, const char *file_name , int iteration , int feedback_level ) + * @par Description: + * This API plays a predefined rhythmic haptic-vibration pattern file (only supports .ivt type file, Immersion VibeTonz).\n + * The first in parameter dev_handle should be from the return value of device_haptic_open().\n + * The second in parameter file_name sets rhythmic vibration pattern file with path. + * It only supports *.ivt type pattern file. \n + * The third in parameter iteration sets the number of iterations to be played. + * This should be less than the maximum iteration range set for the device (currently its 255). + * If you want to play indefinitely, use HAPTIC_INFINITE_ITERATION defined value. But it depends on the target hardware.\n + * The fourth in parameter is the vibration feedback intensity level. + * This level is already predefined by enumeration type value from HAPTIC _FEEDBACK_LEVEL_1 to HAPTIC _FEEDBACK_LEVEL_5. + * If you want to use the value selected by the user in the Setting application menu, just set HAPTIC_FEEDBACK_LEVEL_AUTO value. + * (But the application must have a main loop to use the HAPTIC_FEEDBACK_LEVEL_AUTO value ) \n + * On success it returns a zero value. In case of failure it returns a negative value. \n + * Note: The actual behavior of the feedback play pattern and the intensity depends on the target hardware. + * @param[in] dev_handle set recived dev_handle value from device_haptic_open() + * @param[in] file_name set file name with path + * @param[in] iteration set iteration count + * @param[in] feedback_level set feed_back level value ( it is dependent on target's hardware ) + * @return if it succeed, it return zero value , otherwise negative value return + * @see device_haptic_play_pattern(), device_haptic_play_monotone(), device_haptic_stop_play() + * @par Example + * @code + * ... + * ret_val = device_haptic_play_file(dev_handle, "test.ivt", HAPTIC_TEST_ITERATION , HAPTIC_FEEDBACK_LEVEL_3); + * if(ret_val !=0) + * return -1; + * ... + * @endcode + */ + + int device_haptic_play_file(int dev_handle, const char *file_name, + int iteration, int feedback_level); + +/** + * @fn int device_haptic_play_buffer(int dev_handle, const unsigned char *vibe_buffer, int iteration , int feedback_level ) + * @par Description: + * This API plays a predefined rhythmic haptic-vibration pattern file (only supports .ivt type file, Immersion VibeTonz).\n + * The first in parameter dev_handle should be from the return value of device_haptic_open().\n + * The second in parameter vibe_buffer sets rhythmic vibration pattern buffer. + * The third in parameter iteration sets the number of iterations to be played. + * This should be less than the maximum iteration range set for the device (currently its 255). + * If you want to play indefinitely, use HAPTIC_INFINITE_ITERATION defined value. But it depends on the target hardware.\n + * The fourth in parameter is the vibration feedback intensity level. + * This level is already predefined by enumeration type value from HAPTIC _FEEDBACK_LEVEL_1 to HAPTIC _FEEDBACK_LEVEL_5. + * If you want to use the value selected by the user in the Setting application menu, just set HAPTIC_FEEDBACK_LEVEL_AUTO value. + * (But the application must have a main loop to use the HAPTIC_FEEDBACK_LEVEL_AUTO value ) \n + * On success it returns a zero value. In case of failure it returns a negative value. \n + * Note: The actual behavior of the feedback play pattern and the intensity depends on the target hardware. + * @param[in] dev_handle set recived dev_handle value from device_haptic_open() + * @param[in] buffer set buffer to be played + * @param[in] iteration set iteration count + * @param[in] feedback_level set feed_back level value ( it is dependent on target's hardware ) + * @return if it succeed, it return zero value , otherwise negative value return + * @see device_haptic_play_pattern(), device_haptic_play_monotone(), device_haptic_stop_play() + * @par Example + * @code + * ... + * ret_val = device_haptic_play_buffer(dev_handle, buffer, HAPTIC_TEST_ITERATION , HAPTIC_FEEDBACK_LEVEL_3); + * if(ret_val !=0) + * return -1; + * ... + * @endcode + */ + + int device_haptic_play_buffer(int dev_handle, const unsigned char *vibe_buffer, + int iteration, int feedback_level); + +/** + * @fn int device_haptic_play_monotone(int dev_handle, int duration) + * @par Description: + * This API plays a monotonous haptic-vibration pattern with a constant intensity. \n + * In this monotone play, the intensity used is the value that the user has selected in the Setting application menu.\n + * The first in parameter dev_handle should be from the return value of device_haptic_open().\n + * The second in parameter duration defines the length of time this vibration should be played. + * This duration is in milliseconds. \n + * On success it returns a zero value. In case of failure it returns a negative value. \n + * Note: The actual behavior of the feedback played and the intensity depends on the target hardware. + * @param[in] dev_handle set recived dev_handle value from device_haptic_open() + * @param[in] duration set duration times (ms) + * @return if it succeed, it return zero value, otherwise negative value return + * @see device_haptic_play_pattern(), device_haptic_play_file(), device_haptic_stop_play() + * @par Example + * @code + * ... + * //Play a monotone pattern for 1s == 1000ms + * ret_val = device_haptic_play_monotone(dev_handle, 1000); + * if(ret_val !=0) + * return -1; + * ... + * @endcode + */ + + int device_haptic_play_monotone(int dev_handle, int duration); + +/** + * @fn int device_haptic_stop_play(int dev_handle) + * @par Description: + * This API stops the current vibration being played.\n + * The first in parameter dev_handle should be from the return value of device_haptic_open().\n + * On success it returns a zero value. In case of failure it returns a negative value. + * @param[in] dev_handle set recived dev_handle value from device_haptic_open() + * @return if it succeed, it return zero value , otherwise negative value return + * @see device_haptic_play_pattern(), device_haptic_play_file(), device_haptic_play_monotone() + * @par Example + * @code + * ... + * //Stop the pattern immediately + * ret_val = device_haptic_stop_play(dev_handle); + * if(ret_val !=0) + * return -1; + * ... + * @endcode + */ + + int device_haptic_stop_play(int dev_handle); + +/** + * @fn int device_haptic_get_buffer_duration(int dev_handle, const unsigned char* vibe_buffer , int* duration) + * @par Description: + * This API gets a duration time value from a predefined rhythmic vibration pattern.\n + * The first in parameter dev_handle should be from the return value of device_haptic_open().\n + * The second in parameter vibe_buffer sets rhythmic vibration pattern buffer. + * The application can get a duration time value from the third out parameter duration when this API succeeds. + * The unit of duration is ms (millisecond) \n + * On success it returns a zero value. In case of failure it returns a negative value. \n + * Note: The actual behavior of the feedback played and the intensity depends on the target hardware. + * @param[in] dev_handle set recived dev_handle value from device_haptic_open() + * @param[in] vibe_buffer set vibe pattern buffer to get duration + * @param[out] duration get duration times (ms) + * @return if it succeed, it return zero value , otherwise negative value return + * @see device_haptic_get_file_duration() + */ + + int device_haptic_get_buffer_duration(int dev_handle, const unsigned char *vibe_buffer, + int *duration); + +/** + * @fn int device_haptic_get_pattern_duration(int dev_handle, int pattern , int* duration) + * @par Description: + * This API gets a duration time value from a predefined rhythmic vibration pattern.\n + * The first in parameter dev_handle should be from the return value of device_haptic_open().\n + * The second in parameter pattern should be from a predefined pattern list + * which is available in an enumeration (effectvibe_pattern_list). \n + * The application can get a duration time value from the third out parameter duration when this API succeeds. + * The unit of duration is ms (millisecond) \n + * On success it returns a zero value. In case of failure it returns a negative value. \n + * Note: The actual behavior of the feedback played and the intensity depends on the target hardware. + * @param[in] dev_handle set recived dev_handle value from device_haptic_open() + * @param[in] pattern set predefined pattern enum value from + * @param[out] duration get duration times (ms) + * @return if it succeed, it return zero value , otherwise negative value return + * @see device_haptic_get_file_duration() + */ + + int device_haptic_get_pattern_duration(int dev_handle, int pattern, + int *duration); + +/** + * @fn int device_haptic_get_file_duration(int dev_handle, const char *file_name , int* duration) + * @par Description: + * This API gets a duration time value from a predefined rhythmic vibration pattern file (only supports .ivt type file).\n + * The first in parameter ?dev_handle? should be from the return value of device_haptic_open().\n + * The second in parameter ?file_name? sets rhythmic vibration pattern file with path. It only supports *.ivt type pattern file.\n + * The application can get a duration time value from the third out parameter duration when this API succeeds. + * The unit of duration is ms (millisecond)\n + * On success it returns a zero value. In case of failure it returns a negative value. \n + * Note: The actual behavior of the feedback played and the intensity depends on the target hardware. + * @param[in] dev_handle set recived dev_handle value from device_haptic_open() + * @param[in] file_name set file name with path + * @param[out] duration get duration times (ms) + * @return if it succeed, it return zero value , otherwise negative value return + * @see device_haptic_get_pattern_duration() + */ + + int device_haptic_get_file_duration(int dev_handle, + const char *file_name, + int *duration); + +/** + * @fn int device_haptic_get_device_count(void) + * @par Description: + * This API gets a numer of devices.\n + * The application can get a number of devices from the return value this API succeeds. + * On success it returns a number of devices. In case of failure it returns a negative value. \n + * @return if it succeed, it return number of devices, otherwise negative value return + */ + int device_haptic_get_device_count(void); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif +#endif diff --git a/devman_haptic.pc.in b/devman_haptic.pc.in new file mode 100644 index 0000000..5cb1018 --- /dev/null +++ b/devman_haptic.pc.in @@ -0,0 +1,13 @@ +# Package Information for pkg-config + +prefix=@PREFIX@ +exec_prefix=@EXEC_PREFIX@ +libdir=@LIBDIR@ +includedir=@INCLUDEDIR@ + +Name: devman_haptic +Description: SLP devman haptic library +Version: @VERSION@ +Requires: +Libs: -L${libdir} -ldevman +Cflags: -I${includedir} diff --git a/devman_haptic_ext.h b/devman_haptic_ext.h new file mode 100644 index 0000000..669bfa0 --- /dev/null +++ b/devman_haptic_ext.h @@ -0,0 +1,1303 @@ +/* + * devman + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: DongGi Jang + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * +*/ + + +#ifndef __DEVMAN_HAPTIC_EXT_H__ +#define __DEVMAN_HAPTIC_EXT_H__ + +#include "devman_haptic_ext_core.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @file devman_haptic_ext.h + * @ingroup DEVICE_MANAGER + * @brief This file contains the prototypes of the haptic extended API + * @author SLP2.0 + * @date 2010-01-24 + * @version 0.1 + */ + +/** + * @addtogroup DEVICE_MANAGER + * @{ + */ + +/** + * @fn int device_haptic_get_device_state(int device_index, int *state) + * @par Description: + * This API gets the status bits of an available device that is supported by the TouchSense Player API.\n + * @param[in] dev_idx set a device index (predefined enum value by haptic_dev_idx) + * @param[out] state is a pointer to the variable that will receive the status bits of the device + * @return if it succeed, it return HAPTIC_S_SUCCESS, otherwise negative value return + * @par Example: + * @code + * ... + * int status; + * int state + * + * //Get the haptic device state + * status = device_haptic_get_device_state(DEV_IDX_0, &state); + * if(status < 0) + * return -1; + * ... + * @endcode + */ + + int device_haptic_get_device_state(int device_index, int *state); + +/** + * @fn int device_haptic_get_device_capability_bool(int device_index, int device_cap_type, unsigned char *device_cap_value) + * @par Description: + * This API gets a Boolean capability of an available device that is supported by the TouchSense Player API.\n + * @param[in] device_index set a device index (predefined enum value by haptic_dev_idx) + * @param[in] device_cap_type set capability type of the Boolean capability to get + * @param[out] device_cap_value is a pointer to the variable that will receive the requested Boolean capability value of the device + * @return if it succeed, it return HAPTIC_S_SUCCESS , otherwise negative value return + * @see device_haptic_close() + * @par Example: + * @code + * ... + * int status; + * unsigned char device_cap_value; + * + * //Get haptic device capability + * status = device_haptic_get_device_capability_bool(DEV_IDX_0, NOT_AVAILABLE_CAPABILITY, &device_cap_value); + * if(status < 0) + * return -1; + * ... + * @endcode + */ + + int device_haptic_get_device_capability_bool(int device_index, int device_cap_type, unsigned char *device_cap_value); + +/** + * @fn int device_haptic_get_device_capability_int32(int device_index, int device_cap_type, int *device_cap_value) + * @par Description: + * This API gets a 32-bit integer capability of an available device that is supported by the TouchSense Player API.\n + * @param[in] device_index set a device index (predefined enum value by haptic_dev_idx) + * @param[in] device_cap_type set Capability type of the Boolean capability to get + * @param[out] device_cap_value is a pointer to the variable that will receive the requested 32-bit integer capability value of the device + * @return if it succeed, it return HAPTIC_S_SUCCESS , otherwise negative value return + * @see device_haptic_close() + * @par Example: + * @code + * ... + * int status; + * int device_cap_value; + * + * //Get haptic device capability + * status = device_haptic_get_device_capability_int32(DEV_IDX_0, HAPTIC_DEVCAPTYPE_ACTUATOR_TYPE, &device_cap_value); + * if(status < 0) + * return -1; + * ... + * @endcode + */ + + int device_haptic_get_device_capability_int32(int device_index, int device_cap_type, int *device_cap_value); + +/** + * @fn int device_haptic_get_device_capability_string(int device_index, int device_cap_type, int size, char *device_cap_value) + * @par Description: + * This API gets a string capability of an available device that is supported by the TouchSense Player API.\n + * @param[in] device_index set a device index (predefined enum value by haptic_dev_idx) + * @param[in] device_cap_type set Capability type of the Boolean capability to get + * @param[out] device_cap_value is a pointer to the variable that will receive the requested 32-bit integer capability value of the device + * @return if it succeed, it return HAPTIC_S_SUCCESS , otherwise negative value return + * @see device_haptic_close() + * @par Example: + * @code + * ... + * int status; + * int size = 1024; + * char device_cap_value[size]; + * + * //Get haptic device capability + * status = device_haptic_get_device_capability_string(DEV_IDX_0, HAPTIC_DEVCAPTYPE_DEVICE_NAME, size, device_cap_value); + * if(status < 0) + * return -1; + * ... + * @endcode + */ + + int device_haptic_get_device_capability_string(int device_index, int device_cap_type, int size, char *device_cap_value); + +/** + * @fn int device_haptic_get_device_property_bool(int device_handle, int device_prop_type, unsigned char *device_prop_value) + * @par Description: + * This API gets a Boolean property of an open device.\n + * @param[in] device_handle is a handle to the device for which to get a Boolean property + * @param[in] device_prop_type set property type of the Boolean property to get + * @param[out] device_prop_value is a pointer to the variable that will receive the requested Boolean property value of the device + * @return if it succeed, it return HAPTIC_S_SUCCESS , otherwise negative value return + * @see device_haptic_close() + * @par Example: + * @code + * ... + * int status; + * int device_handle; + * unsigned char device_prop_value; + * + * device_handle = device_haptic_open_device(DEV_IDX0, 0); + * ... + * + * //Get haptic device property + * status = device_haptic_get_device_property_bool(device_handle, HAPTIC_DEVPROPTYPE_DISABLE_EFFECTS, &device_prop_value); + * if(status < 0) + * return -1; + * ... + * @endcode + */ + + int device_haptic_get_device_property_bool(int device_handle, int device_prop_type, unsigned char *device_prop_value); + +/** + * @fn int device_haptic_set_device_property_bool(int device_handle, int device_prop_type, unsigned char device_prop_value) + * @par Description: + * This API sets a Boolean property of an open device.\n + * @param[in] device_handle is a handle to the device for which to set a Boolean property + * @param[in] device_prop_type set property type of the Boolean property to set + * @param[in] device_prop_value is a value of the Boolean property to set + * @return if it succeed, it return HAPTIC_S_SUCCESS , otherwise negative value return + * @see device_haptic_close() + * @par Example: + * @code + * ... + * int status; + * int device_handle; + * unsigned char device_prop_value = HAPTIC_FALSE; + * + * device_handle = device_haptic_open_device(DEV_IDX0, 0); + * ... + * + * //Get haptic device property + * status = device_haptic_set_device_property_bool(device_handle, HAPTIC_DEVPROPTYPE_DISABLE_EFFECTS, device_prop_value); + * if(status < 0) + * return -1; + * ... + * @endcode + */ + + int device_haptic_set_device_property_bool(int device_handle, int device_prop_type, unsigned char device_prop_value); + +/** + * @fn int device_haptic_get_device_property_int32(int device_handle, int device_prop_type, int *device_prop_value) + * @par Description: + * This API gets a 32-bit integer property of an open device.\n + * @param[in] device_handle is a handle to the device for which to get a 32-bit integer property + * @param[in] device_prop_type set property type of the Boolean property to get + * @param[in] device_prop_value is a pointer to the variable that will receive the requested 32-bit integer property value of the device + * @return if it succeed, it return HAPTIC_S_SUCCESS , otherwise negative value return + * @see device_haptic_close() + * @par Example: + * @code + * ... + * int status; + * int device_handle; + * int device_prop_value; + * + * device_handle = device_haptic_open_device(DEV_IDX0, 0); + * ... + * + * //Get haptic device property + * status = device_haptic_get_device_property_int32(device_handle, HAPTIC_DEVPROPTYPE_STRENGTH, &device_prop_value); + * if(status < 0) + * return -1; + * ... + * @endcode + */ + + int device_haptic_get_device_property_int32(int device_handle, int device_prop_type, int *device_prop_value); + +/** + * @fn int device_haptic_set_device_property_int32(int device_handle, int device_prop_type, int device_prop_value) + * @par Description: + * This API sets a 32-bit integer property of an open device.\n + * @param[in] device_handle is a handle to the device for which to set a 32-bit integer property + * @param[in] device_prop_type set property type of the Boolean property to set + * @param[in] device_prop_value is a value of the 32-bit integer property to set. + * @return if it succeed, it return HAPTIC_S_SUCCESS , otherwise negative value return + * @see device_haptic_close() + * @par Example: + * @code + * ... + * int status; + * int device_handle; + * int device_prop_value = 5000; + * + * device_handle = device_haptic_open_device(DEV_IDX0, 0); + * ... + * + * //Get haptic device property + * status = device_haptic_get_device_property_int32(device_handle, HAPTIC_DEVPROPTYPE_STRENGTH, device_prop_value); + * if(status < 0) + * return -1; + * ... + * @endcode + */ + + int device_haptic_set_device_property_int32(int device_handle, int device_prop_type, int device_prop_value); + +/** + * @fn int device_haptic_get_device_property_string(int device_handle, int device_prop_type, int size, char *device_prop_value) + * @par Description: + * This API gets a string property of an open device.\n + * @param[in] device_handle is a handle to the device for which to get a string property + * @param[in] device_prop_type set property type of the string property to get + * @param[in] size is a size of the buffer, in bytes, pointed to by the device_prop_value parameter. + * @param[out] device_prop_value is a pointer to the variable that will receive the requested string property value of the device + * @return if it succeed, it return HAPTIC_S_SUCCESS , otherwise negative value return + * @see device_haptic_close() + * @par Example: + * @code + * ... + * int status; + * int device_handle; + * int size = 1024; + * char device_prop_value[size]; + * + * device_handle = device_haptic_open_device(DEV_IDX0, 0); + * ... + * + * //Get haptic device property + * status = device_haptic_get_device_property_string(device_handle, HAPTIC_DEVPROPTYPE_STRENGTH, size, device_prop_value); + * if(status < 0) + * return -1; + * ... + * @endcode + */ + + int device_haptic_get_device_property_string(int device_handle, int device_prop_type, int size, char *device_prop_value); + +/** + * @fn int device_haptic_set_device_property_string(int device_handle, int device_prop_type, char *device_prop_value) + * @par Description: + * This API sets a string property of an open device.\n + * @param[in] device_handle is a handle to the device for which to get a string property + * @param[in] device_prop_type set property type of the string property to set + * @param[in] device_prop_value pointer to the character buffer containing the string property value to set. + * @return if it succeed, it return HAPTIC_S_SUCCESS , otherwise negative value return + * @see device_haptic_close() + * @par Example: + * @code + * ... + * int status; + * int device_handle; + * char *device_prop_value = "DMZI13021KAIA112123"; + * + * device_handle = device_haptic_open_device(DEV_IDX0, 0); + * ... + * + * //Get haptic device property + * status = device_haptic_set_device_property_string(device_handle, HAPTIC_DEVPROPTYPE_LICENSE_KEY, device_prop_value); + * if(status < 0) + * return -1; + * ... + * @endcode + */ + + int device_haptic_set_device_property_string(int device_handle, int device_prop_type, const char *device_prop_value); + +/** + * @fn int device_haptic_get_effect_count(const unsigned char *ivt_buffer) + * @par Description: + * This API gets number of effects defined in IVT data.\n + * @param[in] ivt_buffer is a pointer to IVT data + * @return if it succeed, it returns number of effects defined in the specified IVT data, otherwise negative value return + * @par Example: + * @code + * ... + * int effect_count; + * unsigned char ivt_buffer = { .... }; + * + * //Open the haptic device + * effect_count = device_haptic_get_effect_count(ivt_buffer); + * if(effect_count < 0) + * return -1; + * ... + * @endcode + */ + + int device_haptic_get_effect_count(const unsigned char *ivt_buffer); + +/** + * @fn int device_haptic_get_effect_name(const unsigned char *ivt_buffer, int effect_index, int size, char *effect_name) + * @par Description: + * This API Gets the name of an effect defined in IVT data.\n + * @param[in] ivt_buffer is a pointer to IVT data containing the effect for which to get the name + * @param[in] effect_index is index of the effect for which to get the name + * @param[in] size is a size of the buffer, in bytes, pointed by the effect_name parameter + * @param[out] effect_name is a pointer to the character buffer that will receive the name of the effect + * @return if it succeed, it return HAPTIC_S_SUCCESS, otherwise negative value return + * @par Example: + * @code + * ... + * int status; + * unsigned char *ivt_buffer = { ... }; + * int size = 1024; + * char effect_name[size]; + * + * //Get IVT effect duration + * status = device_haptic_get_effect_name(ivt_buffer, 0, size, effect_name); + * if(staus < 0) + * return -1; + * ... + * @endcode + */ + + int device_haptic_get_effect_name(const unsigned char *ivt_buffer, int effect_index, int size, char *effect_name); + +/** + * @fn int device_haptic_get_effect_name_u(const unsigned char *ivt_buffer, int effect_index, int size, unsigned short *effect_name) + * @par Description: + * This API gets the name of an effect defined in IVT data as a string of VibeWChar in UCS-2 format.\n + * @param[in] ivt_buffer is a pointer to IVT data containing the effect for which to get the name + * @param[in] effect_index is index of the effect for which to get the name + * @param[in] size is a size of the buffer, in bytes, pointed by the effect_name parameter + * @param[out] effect_name is a pointer to the unsigned short buffer that will receive the name of the effect + * @return if it succeed, it return HAPTIC_S_SUCCESS, otherwise negative value return + * @par Example: + * @code + * ... + * int status; + * unsigned char *ivt_buffer = { ... }; + * int size = 1024; + * unsigned short effect_name[size]; + * + * //Get IVT effect duration + * status = device_haptic_get_effect_name_u(ivt_buffer, 0, size, effect_name); + * if(staus < 0) + * return -1; + * ... + * @endcode + */ + + int device_haptic_get_effect_name_u(const unsigned char *ivt_buffer, int effect_index, int size, unsigned short *effect_name); + +/** + * @fn int device_haptic_get_effect_index_from_name(const unsigned char *ivt_buffer, const char *effect_name, int *effect_index) + * @par Description: + * This API gets the index of an effect defined in IVT data given the name of the effect.\n + * @param[in] ivt_buffer is a pointer to IVT data + * @param[in] effect_name is pointer to the character buffer containing the name of the effect for which to get the index + * @param[out] effect_index is a pointer to the variable that will receive the index of the effect + * @return if it succeed, it return HAPTIC_S_SUCCESS, otherwise negative value return + * @par Example: + * @code + * ... + * int status; + * unsigned char *ivt_buffer = { ... }; + * int effect_index; + * char *effect_name = "PERIODIC_EFFECT"; + * + * //Get IVT effect duration + * status = device_haptic_get_effect_index_from_name(ivt_buffer, effect_name, &effect_index); + * if(staus < 0) + * return -1; + * ... + * @endcode + */ + + int device_haptic_get_effect_index_from_name(const unsigned char *ivt_buffer, const char *effect_name, int *effect_index); + +/** + * @fn int device_haptic_get_effect_index_from_name_u(const unsigned char *ivt_buffer, const unsigned short *effect_name, int *effect_index) + * @par Description: + * This API Gets the index of an effect defined in IVT data given the name of the effect as a string of VibeWChar in UCS-2 format.\n + * @param[in] ivt_buffer is a pointer to IVT data + * @param[in] effect_name is a pointer to the unsigned short buffer containing the UCS-2 formatted name of the effect for which to get the index + * @param[out] effect_index is a pointer to the variable that will receive the index of the effect + * @return if it succeed, it return HAPTIC_S_SUCCESS, otherwise negative value return + * @par Example: + * @code + * ... + * int status; + * unsigned char *ivt_buffer = { ... }; + * int effect_index; + * unsigned short *effect_name = "PERIODIC_EFFECT"; + * + * //Get IVT effect duration + * status = device_haptic_get_effect_index_from_name_u(ivt_buffer, effect_name, &effect_index); + * if(staus < 0) + * return -1; + * ... + * @endcode + */ + + int device_haptic_get_effect_index_from_name_u(const unsigned char *ivt_buffer, const unsigned short *effect_name, int *effect_index); + +/** + * @fn int device_haptic_play_effect(int device_handle, const unsigned char *ivt_buffer, int effect_index, int *effect_handle) + * @par Description: + * This API Pauses a playing effect.\n + * @param[in] device_handle is a handle to the device associated to the effect + * @param[in] ivt_buffer is a pointer to IVT data containing the definition of the effect to play + * @param[in] effect_index is an index of the effect to play + * @param[out] effect_handle is a pointer to the handle to the variable that will receive a handle to the playing effect + * @return if it succeed, it return HAPTIC_S_SUCCESS, otherwise negative value return + * @see device_haptic_close() + * @par Example: + * @code + * ... + * int status; + * int effect_handle; + * + * status = device_haptic_play_effect(device_handle, ivt_buffer, 0, &effect_handle); + * if (status < 0) { + * return status; + * } + * ... + * @endcode + */ + + int device_haptic_play_effect(int device_handle, const unsigned char *ivt_buffer, int effect_index, int *effect_handle); + +/** + * @fn int device_haptic_play_effect_repeat(int device_handle, const unsigned char *ivt_buffer, int effect_index, unsigned char repeat, int *effect_handle) + * @par Description: + * This API Pauses a playing effect.\n + * @param[in] device_handle is a handle to the device associated to the effect + * @param[in] ivt_buffer is a pointer to IVT data containing the definition of the effect to play + * @param[in] effect_index is an index of the effect to play + * @param[in] repeat is a number of time to repeat the effect + * @param[out] effect_handle is a pointer to the handle to the variable that will receive a handle to the playing effect + * @return if it succeed, it return HAPTIC_S_SUCCESS, otherwise negative value return + * @see device_haptic_close() + * @par Example: + * @code + * ... + * int status; + * int effect_handle; + * + * status = device_haptic_play_effect_repeat(device_handle, ivt_buffer, 0, 3, &effect_handle); + * if (status < 0) { + * return status; + * } + * ... + * @endcode + */ + + int device_haptic_play_effect_repeat(int device_handle, const unsigned char *ivt_buffer, int effect_index, unsigned char repeat, int *effect_handle); + +/** + * @fn int device_haptic_stop_playing_effects(int device_handle, int effect_handle) + * @par Description: + * This API stops playing effect.\n + * @param[in] device_handle is a handle to the device on which to stop the playing effect + * @param[in] effect_handle is a handle to the playing effect to stop + * @return if it succeed, it return HAPTIC_S_SUCCESS, otherwise negative value return + * @par Example: + * @code + * ... + * int status; + * + * status = device_haptic_stop_playing_effects(device_handle, effect_handle); + * if(status < 0) + * return -1; + * ... + * @endcode + */ + + int device_haptic_stop_playing_effect(int device_handle, int effect_handle); + +/** + * @fn int device_haptic_get_effect_type(const unsigned char *ivt_buffer, int effect_index, int *effect_type) + * @par Description: + * This API gets the type of an effect defined in IVT data.\n + * @param[in] ivt_buffer is a pointer to IVT data containing the effect for which to get the type + * @param[in] effect_index is index of the effect for which to get the type + * @param[out] effect_type is a pointer to the variable that will receive the type of the effect + * @return if it succeed, it return HAPTIC_S_SUCCESS, otherwise negative value return + * @par Example: + * @code + * ... + * int status; + * unsigned char *ivt_buffer = { ... }; + * int effect_type; + * + * //Get IVT effect type + * status = device_haptic_get_effect_type(ivt_buffer, 0, &effect_type); + * if(staus < 0) + * return -1; + * ... + * @endcode + */ + + int device_haptic_get_effect_type(const unsigned char *ivt_buffer, int effect_index, int *effect_type); + +/** + * @fn int device_haptic_get_magsweep_effect_definition(const unsigned char *ivt_buffer, int effect_index, int *duration, int *magnitude, int *style, int *attacktime, int *attacklevel, int *fadetime, int *fadelevel); + * @par Description: + * This API gets the parameters of a MagSweep effect defined in IVT data.\n + * @param[in] ivt_buffer is a pointer to IVT data containing the effect for which to get the type + * @param[in] effect_index is index of the effect for which to get the type + * @param[out] duration is a pointer to the variable that will receive the duration of the effect in milliseconds + * @param[out] magnitude is a pointer to the variable that will receive the magnitude of the effect + * @param[out] style is a pointer to the variable that will receive the style of the effect + * @param[out] attacktime is a pointer to the variable that will receive the attack time of the effect in milliseconds + * @param[out] attacklevel is a pointer to the variable that will receive the attack level of the effect + * @param[out] fadetime is a pointer to the variable that will receive the fade time of the effect in milliseconds + * @param[out] fadelevel is a pointer to the variable that will receive the fade level of the effect + * @return if it succeed, it return HAPTIC_S_SUCCESS, otherwise negative value return + * @par Example: + * @code + * ... + * int status; + * unsigned char *ivt_buffer = { ... }; + * int duration; + * int magnitude; + * int style; + * int attacktime; + * int attacklevel; + * int fadetime; + * int fadelevel; + * + * status = device_haptic_get_magsweep_effect_definition(ivt_buffer, 1, + * &duration, &magnitude, &style, &attacktime, &attacklevel, &fadetime, &fadelevel); + * if (status < 0) { + * return status; + * } + * ... + * @endcode + */ + + int device_haptic_get_magsweep_effect_definition(const unsigned char *ivt_buffer, int effect_index, int *duration, int *magnitude, int *style, int *attacktime, int *attacklevel, int *fadetime, int *fadelevel); + +/** + * @fn int device_haptic_get_periodic_effect_definition(const unsigned char *ivt_buffer, int effect_index, int *duration, int *magnitude, int *period, int *style_and_wave_type, int *attacktime, int *attacklevel, int *fadetime, int *fadelevel); + * @par Description: + * This API gets the parameters of a Periodic effect defined in IVT data.\n + * @param[in] ivt_buffer is a pointer to IVT data containing the effect for which to get the type + * @param[in] effect_index is index of the effect for which to get the type + * @param[out] duration is a pointer to the variable that will receive the duration of the effect in milliseconds + * @param[out] magnitude is a pointer to the variable that will receive the magnitude of the effect + * @param[out] period is a pointer to the variable that will receive the period of the effect in milliseconds + * @param[out] style_and_wave_type is a pointer to the variable that will receive the style and wave type of the effect + * @param[out] attacktime is a pointer to the variable that will receive the attack time of the effect in milliseconds + * @param[out] attacklevel is a pointer to the variable that will receive the attack level of the effect + * @param[out] fadetime is a pointer to the variable that will receive the fade time of the effect in milliseconds + * @param[out] fadelevel is a pointer to the variable that will receive the fade level of the effect + * @return if it succeed, it return HAPTIC_S_SUCCESS, otherwise negative value return + * @par Example: + * @code + * ... + * int status; + * unsigned char *ivt_buffer = { ... }; + * int duration; + * int magnitude; + * int period; + * int style; + * int attacktime; + * int attacklevel; + * int fadetime; + * int fadelevel; + * + * status = device_haptic_get_periodic_effect_definition(ivt_buffer, 1, + * &duration, &magnitude, &period, &style, &attacktime, &attacklevel, &fadetime, &fadelevel); + * if (status < 0) { + * return status; + * } + * ... + * @endcode + */ + + int device_haptic_get_periodic_effect_definition(const unsigned char *ivt_buffer, int effect_index, int *duration, int *magnitude, int *period, int *style_and_wave_type, int *attacktime, int *attacklevel, int *fadetime, int *fadelevel); + +/** + * @fn int device_haptic_get_effect_duration(const unsigned char *ivt_buffer, int effect_index, int *effect_duration) + * @par Description: + * This API gets the duration of an effect defined in IVT data.\n + * @param[in] ivt_buffer is a pointer to IVT data containing the effect for which to get the Duration + * @param[in] effect_index is a index of the effect for which to get the Duration + * @param[out] effect_duration is a pointer to the variable that will receive the Duration of the effect + * @return if it succeed, it return HAPTIC_S_SUCCESS, otherwise negative value return + * @par Example: + * @code + * ... + * int status; + * unsigned char *ivt_buffer = { ... }; + * int effect_duration + * + * //Get IVT effect duration + * status = device_haptic_get_effect_duration(ivt_buffer, 0, &effect_duration); + * if(staus < 0) + * return -1; + * ... + * @endcode + */ + + int device_haptic_get_effect_duration(const unsigned char *ivt_buffer, int effect_index, int *effect_duration); + +/** + * @fn int device_haptic_play_magsweep_effect(int device_handle, int duration, int magnitude, int style, int attacktime, int attacklevel, int fadetime, int fadelevel, int *effect_handle); + * @par Description: + * This API play Mag Sweep effect.\n + * @param[in] device_handle is a handle to the device on which to modify the playing effect + * @param[in] duration is a duration of the effect in milliseconds + * @param[in] magnitude is a magnitude of the effect + * @param[in] style is a style of the effect + * @param[in] attacktime is a attack time of the effect in milliseconds + * @param[in] attacklevel is a attack level of the effect + * @param[in] fadetime is a fade time of the effect in milliseconds + * @param[in] fadelevel is a fade level of the effect + * @param[out] effect_handle is a pointer to the variable that will receive a handle to the playing effect + * @return if it succeed, it return HAPTIC_S_SUCCESS, otherwise negative value return + * @par Example: + * @code + * ... + * int status; + * unsigned char *ivt_buffer = { ... }; + * int duration = 2900; + * int magnitude = HAPTIC_MAX_MAGNITUDE; + * int style = HAPTIC_STYLE_SMOOTH; + * int attackTime = 2483; + * int attackLevel = 0; + * int fadeTime = 0; + * int fadeLevel = HAPTIC_MAX_MAGNITUDE; + * int effect_handle; + * + * status = device_haptic_play_magsweep_effect(device_handle, + * duration, magnitude, style, attacktime, attacklevel, fadetime, fadelevel, &effect_handle); + * if (status < 0) { + * return status; + * } + * ... + * @endcode + */ + + int device_haptic_play_magsweep_effect(int device_handle, int duration, int magnitude, int style, int attacktime, int attacklevel, int fadetime, int fadelevel, int *effect_handle); + +/** + * @fn int device_haptic_play_periodic_effect(int device_handle, int duration, int magnitude, int period, int style_and_wave_type, int attacktime, int attacklevel, int fadetime, int fadelevel, int *effect_handle); + * @par Description: + * This API play Periodic effect.\n + * @param[in] device_handle is a handle to the device on which to modify the playing effect + * @param[in] duration is a duration of the effect in milliseconds + * @param[in] magnitude is a magnitude of the effect + * @param[in] style is a style of the effect + * @param[in] attacktime is a attack time of the effect in milliseconds + * @param[in] attacklevel is a attack level of the effect + * @param[in] fadetime is a fade time of the effect in milliseconds + * @param[in] fadelevel is a fade level of the effect + * @param[out] effect_handle is a pointer to the variable that will receive a handle to the playing effect + * @return if it succeed, it return HAPTIC_S_SUCCESS, otherwise negative value return + * @par Example: + * @code + * ... + * int status; + * unsigned char *ivt_buffer = { ... }; + * int duration = 2900; + * int magnitude = HAPTIC_MAX_MAGNITUDE; + * int period = 100; + * int style = HAPTIC_STYLE_SMOOTH; + * int attackTime = 2483; + * int attackLevel = 0; + * int fadeTime = 0; + * int fadeLevel = HAPTIC_MAX_MAGNITUDE; + * int effect_handle; + * + * status = device_haptic_play_periodic_effect(device_handle, + * duration, magnitude, period, style, attacktime, attacklevel, fadetime, fadelevel, &effect_handle); + * if (status < 0) { + * return status; + * } + * ... + * @endcode + */ + + int device_haptic_play_periodic_effect(int device_handle, int duration, int magnitude, int period, int style_and_wave_type, int attacktime, int attacklevel, int fadetime, int fadelevel, int *effect_handle); + +/** + * @fn int device_haptic_modify_playing_magsweep_effect(int device_handle, int effect_handle, int duration, int magnitude, int style, int attacktime, int attacklevel, int fadetime, int fadelevel); + * @par Description: + * This API Modifies a playing Mag Sweep effect.\n + * @param[in] device_handle is a handle to the device on which to modify the playing effect + * @param[in] effect_handle is a handle to the playing MagSweep effect to modify + * @param[in] duration is a duration of the effect in milliseconds + * @param[in] magnitude is a magnitude of the effect + * @param[in] style is a style of the effect + * @param[in] attacktime is a attack time of the effect in milliseconds + * @param[in] attacklevel is a attack level of the effect + * @param[in] fadetime is a fade time of the effect in milliseconds + * @param[in] fadelevel is a fade level of the effect + * @return if it succeed, it return HAPTIC_S_SUCCESS, otherwise negative value return + * @par Example: + * @code + * ... + * int status; + * unsigned char *ivt_buffer = { ... }; + * int duration = 2900; + * int magnitude = HAPTIC_MAX_MAGNITUDE; + * int style = HAPTIC_STYLE_SMOOTH; + * int attackTime = 2483; + * int attackLevel = 0; + * int fadeTime = 0; + * int fadeLevel = HAPTIC_MAX_MAGNITUDE; + * + * status = device_haptic_modify_playing_magsweep_effect(device_handle, effect_handle, + * duration, magnitude, style, attacktime, attacklevel, fadetime, fadelevel); + * if (status < 0) { + * return status; + * } + * ... + * @endcode + */ + + int device_haptic_modify_playing_magsweep_effect(int device_handle, int effect_handle, int duration, int magnitude, int style, int attacktime, int attacklevel, int fadetime, int fadelevel); + +/** + * @fn int device_haptic_modify_playing_periodic_effect(int device_handle, int effect_handle, int duration, int magnitude, int period, int style_and_wave_type, int attacktime, int attacklevel, int fadetime, int fadelevel); + * @par Description: + * This API modifies a playing Periodic effect.\n + * @param[in] device_handle is a handle to the device on which to modify the playing effect + * @param[in] effect_handle is a handle to the playing MagSweep effect to modify + * @param[in] duration is a duration of the effect in milliseconds + * @param[in] magnitude is a magnitude of the effect + * @param[in] period is a period of the effect + * @param[in] style is a style of the effect + * @param[in] attacktime is a attack time of the effect in milliseconds + * @param[in] attacklevel is a attack level of the effect + * @param[in] fadetime is a fade time of the effect in milliseconds + * @param[in] fadelevel is a fade level of the effect + * @return if it succeed, it return HAPTIC_S_SUCCESS, otherwise negative value return + * @par Example: + * @code + * ... + * int status; + * unsigned char *ivt_buffer = { ... }; + * int duration = 2900; + * int magnitude = HAPTIC_MAX_MAGNITUDE; + * int period = 100; + * int style = HAPTIC_STYLE_SMOOTH; + * int attackTime = 2483; + * int attackLevel = 0; + * int fadeTime = 0; + * int fadeLevel = HAPTIC_MAX_MAGNITUDE; + * + * status = device_haptic_modify_playing_periodic_effect(device_handle, effect_handle, + * duration, magnitude, period, style, attacktime, attacklevel, fadetime, fadelevel); + * if (status < 0) { + * return status; + * } + * ... + * @endcode + */ + + int device_haptic_modify_playing_periodic_effect(int device_handle, int effect_handle, int duration, int magnitude, int period, int style_and_wave_type, int attacktime, int attacklevel, int fadetime, int fadelevel); + +/** + * @fn int device_haptic_create_streaming_effect(int device_handle, int *effect_handle) + * @par Description: + * This API creates a Streaming effect.\n + * @param[in] device_handle is a handle to the device associated to the effect + * @param[out] effect_handle is a pointer to the variable that will receive a handle to the Streaming effect + * @return if it succeed, it return HAPTIC_S_SUCCESS, otherwise negative value return + * @par Example: + * @code + * ... + * int status; + * int effect_handle; + * + * status = device_haptic_create_streaming_effect(device_handle, &effect_handle); + * if(status < 0) + * return -1; + * ... + * @endcode + */ + + int device_haptic_create_streaming_effect(int device_handle, int *effect_handle); + +/** + * @fn int device_haptic_destroy_streaming_effect(int device_handle, int effect_handle) + * @par Description: + * This API creates a Streaming effect.\n + * @param[in] device_handle is a handle to the device associated to the effect + * @param[in] effect_handle is a handle to the Streaming effect to destroy + * @return if it succeed, it return HAPTIC_S_SUCCESS, otherwise negative value return + * @par Example: + * @code + * ... + * int status; + * int effect_handle; + * + * status = device_haptic_create_streaming_effect(device_handle, &effect_handle); + * if(status < 0) + * return -1; + * ... + * @endcode + */ + + int device_haptic_destroy_streaming_effect(int device_handle, int effect_handle); + +/** + * @fn int device_haptic_play_streaming_sample(int device_handle, int effect_handle, const unsigned char *streaming_sample, int size) + * @par Description: + * This API plays a Streaming Sample given the parameters defining the effect.\n + * @param[in] device_handle is a handle to the device on which to play the effect + * @param[in] effect_handle is a hndle to the Streaming effect to play + * @param[in] streaming_sameple is a pointer to Streaming Sample data containing the definition of the effect to play + * @param[in] size is a size of the buffer, in bytes, pointed to by streaming_sample parameter + * @return if it succeed, it return HAPTIC_S_SUCCESS, otherwise negative value return + * @par Example: + * @code + * ... + * int status; + * + * status = device_haptic_play_streaming_sample(device_handle, effect_handle, *streaming_sample, size); + * if(status < 0) + * return -1; + * ... + * @endcode + */ + + int device_haptic_play_streaming_sample(int device_handle, int effect_handle, const unsigned char *streaming_sample, int size); + +/** + * @fn int device_haptic_play_streaming_sample_with_offset(int device_handle, int effect_handle, const unsigned char *streaming_sample, int size, int offset_time) + * @par Description: + * This API plays a Streaming Sample with a time offset given the parameters defining the effect.\n + * @param[in] device_handle is a handle to the device on which to play the effect + * @param[in] effect_handle is a hndle to the Streaming effect to play + * @param[in] streaming_sameple is a pointer to Streaming Sample data containing the definition of the effect to play + * @param[in] size is a size of the buffer, in bytes, pointed to by streaming_sample parameter + * @param[in] offset_time is set offet time to play the sample + * @return if it succeed, it return HAPTIC_S_SUCCESS, otherwise negative value return + * @par Example: + * @code + * ... + * int status; + * + * status = device_haptic_play_streaming_sample_with_offset(device_handle, effect_handle, *streaming_sample, size, 100); + * if(status < 0) + * return -1; + * ... + * @endcode + */ + + int device_haptic_play_streaming_sample_with_offset(int device_handle, int effect_handle, const unsigned char *streaming_sample, int size, int offset_time); + + + +/** + * @fn int device_haptic_stop_all_playing_effects(int device_handle) + * @par Description: + * This API stops all playing and paused effects on a device.\n + * @param[in] device_handle is a handle to the device associated to the effect + * @return if it succeed, it return HAPTIC_S_SUCCESS, otherwise negative value return + * @par Example: + * @code + * ... + * int status; + * + * status = device_haptic_stop_all_playing_effects(device_handle); + * if(status < 0) + * return -1; + * ... + * @endcode + */ + + int device_haptic_stop_all_playing_effects(int device_handle); + +/** + * @fn int device_haptic_save_file(const unsigned char *ivt_buffer, const char *path_name) + * @par Description: + * This API saves an IVT file to persistent storage.\n + * @param[in] ivt_buffer is a pointer to IVT data + * @param[in] path_name is a pointer to the character buffer containing the path name of the file to save + * @return if it succeed, it return HAPTIC_S_SUCCESS, otherwise negative value return + * @par Example: + * @code + * ... + * int status; + * unsigned char *ivt_buffer = { ... }; + * char *path_name = "test.ivt"; + * + * status = device_haptic_save_file(ivt_buffer, path_name); + * if(staus < 0) + * return -1; + * ... + * @endcode + */ + + int device_haptic_save_file(const unsigned char *ivt_buffer, const char *path_name); + +/** + * @fn int device_haptic_delete_file(const char *path_name) + * @par Description: + * This API removes an IVT file from persistent storage.\n + * @param[in] path_name is a pointer to the character buffer containing the path name of the file to remove.\n + * @return if it succeed, it return HAPTIC_S_SUCCESSe , otherwise negative value return + * @see device_haptic_save_file() + * @par Example: + * @code + * ... + * char *path_name = "test.ivt"; + * int = status; + * + * //Remove an IVT file + * status = device_haptic_delete_file(path_name); + * if(status < 0) + * return -1; + * ... + * @endcode + */ + + int device_haptic_delete_file(const char *path_name); + +/** + * @fn int device_haptic_pause_playing_effect(int device_handle, int effect_handle) + * @par Description: + * This API Pauses a playing effect.\n + * @param[in] device_handle is a handle to the device associated to the effect + * @param[in] effect_handle is a handle to the playing effect to pause + * @return if it succeed, it return HAPTIC_S_SUCCESS, otherwise negative value return + * @par Example: + * @code + * ... + * int status; + * + * status = device_haptic_pause_playing_effect(handle, effect_handle); + * if (status < 0) { + * return status; + * } + * ... + * @endcode + */ + + int device_haptic_pause_playing_effect(int device_handle, int effect_handle); + +/** + * @fn int device_haptic_resume_paused_effect(int device_handle, int effect_handle) + * @par Description: + * This API resumes a paused effect from the point where the effect was paused.\n + * @param[in] device_handle is a handle to the device associated to the effect + * @param[in] effect_handle is a handle to the playing effect to pause + * @return if it succeed, it return HAPTIC_S_SUCCESS, otherwise negative value return + * @par Example: + * @code + * ... + * int status; + * + * status = device_haptic_resume_paused_effect(handle, effect_handle); + * if (status < 0) { + * return status; + * } + * ... + * @endcode + */ + + int device_haptic_resume_paused_effect(int device_handle, int effect_handle); + +/** + * @fn int device_haptic_get_effect_state(int device_handle, int effect_handle, int *effect_state) + * @par Description: + * This API retrieves the status of an effect (playing, not playing, paused).\n + * @param[in] device_handle ia a handle to the device associated to the effect + * @param[in] effect_handle ia a handle to the effect which must have been obtained by calling playing APIs + * @param[out] state ia a pointer to the variable that will receive the status bits of the effect + * @return if it succeed, it return HAPTIC_S_SUCCESS, otherwise negative value return + * @par Example: + * @code + * ... + * int status; + * + * //Open the haptic device + * status = device_haptic_get_effect_state(device_handle, device_effect, &state); + * if(status < 0) + * return -1; + * ... + * @endcode + */ + + int device_haptic_get_effect_state(int device_handle, int effect_handle, int *effect_state); + +/** + * @fn int device_haptic_get_size(const unsigned char *ivt_buffer, int size) + * @par Description: + * This API sets the size of IVT data.\n + * @param[in] ivt_buffer is a pointer to an IVT buffer + * @param[in] size is a size of the buffer pointed to by ivt_buffer + * @return if it succeed, it return the size of the IVT data, otherwise negative value return + * @par Example: + * @code + * ... + * int status; + * unsigned char *ivt_buffer = { ... }; + * int IVT_size; + * + * IVT_size = device_haptic_get_size(ivt_buffer, sizeof(ivt_buffer)); + * if (status < 0) { + * return status; + * } + * ... + * @endcode + */ + + int device_haptic_get_size(const unsigned char *ivt_buffer, int size); + +/** + * @fn int device_haptic_initialize_buffer(unsigned char *ivt_buffer, int size) + * @par Description: + * This API initializes an IVT buffer. Any data currently in the buffer will be destroyed.\n + * @param[in/out] ivt_buffer is a pointer to a buffer to initialize + * @param[in] size is a size of the buffer pointed to by ivt_buffer + * @return if it succeed, it return HAPTIC_S_SUCCESS, otherwise negative value return + * @par Example: + * @code + * ... + * int status; + * int size = 1024; + * unsigned char ivt_buffer[size]; + * + * status = device_haptic_initialize_buffer(ivt_buffer, size); + * if (status < 0) { + * return status; + * } + * ... + * @endcode + */ + + int device_haptic_initialize_buffer(unsigned char *ivt_buffer, int size); + +/** + * @fn int device_haptic_insert_element(unsigned char *ivt_buffer, int size, int timeline_index, const HapticElement *element) + * @par Description: + * This API inserts an element into a Timeline effect in an IVT buffer.\n + * @param[in/out] ivt_buffer is a pointer to an IVT buffer + * @param[in] size is a size of the buffer pointed to by ivt_buffer + * @param[in] timeline_index is an index of a Timeline effect in which to insert the element + * @param[in] element is a pointer to an HapticElement structure containing the parameters of a Periodic effect, MagSweep effect, or Repeat event to insert into the Timeline effect + * @return if it succeed, it return HAPTIC_S_SUCCESS, otherwise negative value return + * @par Example: + * @code + * ... + * int status; + * HapticElement elem1; + * elem1.elementtype = HAPTIC_ELEMTYPE_MAGSWEEP; + * elem1.time = 0; + * elem1.TypeSpecific.magsweep.duration = 2900; + * elem1.TypeSpecific.magsweep.magnitude = HAPTIC_MAX_MAGNITUDE; + * elem1.TypeSpecific.magsweep.style = HAPTIC_STYLE_SMOOTH; + * elem1.TypeSpecific.magsweep.attacktime = 2483; + * elem1.TypeSpecific.magsweep.attacklevel = 0; + * elem1.TypeSpecific.magsweep.fadetime = 0; + * elem1.TypeSpecific.magsweep.fadelevel = HAPTIC_MAX_MAGNITUDE; + * + * status = device_haptic_insert_element(temp_buffer, temp_size, timeline_index, &elem1); + * if (status < 0) { + * return status; + * } + + * ... + * @endcode + */ + + int device_haptic_insert_element(unsigned char *ivt_buffer, int size, int timeline_index, const HapticElement *element); + +/** + * @fn int device_haptic_insert_element2(unsigned char *ivt_buffer, int size, int timeline_index, const HapticElement2 *element) + * @par Description: + * This API inserts an element into a Timeline effect in an IVT buffer.\n + * @param[in/out] ivt_buffer is a pointer to an IVT buffer + * @param[in] size is a size of the buffer pointed to by ivt_buffer + * @param[in] timeline_index is an index of a Timeline effect in which to insert the element + * @param[in] element is a pointer to an HapticElement2 structure containing the parameters of a Periodic effect, MagSweep effect, or Repeat event to insert into the Timeline effect + * @return if it succeed, it return HAPTIC_S_SUCCESS, otherwise negative value return + * @par Example: + * @code + * ... + * int status; + * HapticElement2 elem1; + * elem1.elementtype = HAPTIC_ELEMTYPE_MAGSWEEP; + * elem1.time = 0; + * elem1.TypeSpecific.magsweep.duration = 2900; + * elem1.TypeSpecific.magsweep.magnitude = HAPTIC_MAX_MAGNITUDE; + * elem1.TypeSpecific.magsweep.style = HAPTIC_STYLE_SMOOTH; + * elem1.TypeSpecific.magsweep.attacktime = 2483; + * elem1.TypeSpecific.magsweep.attacklevel = 0; + * elem1.TypeSpecific.magsweep.fadetime = 0; + * elem1.TypeSpecific.magsweep.fadelevel = HAPTIC_MAX_MAGNITUDE; + * + * status = device_haptic_insert_element2(temp_buffer, temp_size, timeline_index, &elem1); + * if (status < 0) { + * return status; + * } + + * ... + * @endcode + */ + + int device_haptic_insert_element2(unsigned char *ivt_buffer, int size, int timeline_index, const HapticElement2 *element); + +/** + * @fn int device_haptic_insert_element3(unsigned char *ivt_buffer, int size, int timeline_index, const HapticElement3 *element) + * @par Description: + * This API inserts an element into a Timeline effect in an IVT buffer.\n + * @param[in/out] ivt_buffer is a pointer to an IVT buffer + * @param[in] size is a size of the buffer pointed to by ivt_buffer + * @param[in] timeline_index is an index of a Timeline effect in which to insert the element + * @param[in] element is a pointer to an HapticElement3 structure containing the parameters of a Periodic effect, MagSweep effect, or Repeat event to insert into the Timeline effect + * @return if it succeed, it return HAPTIC_S_SUCCESS, otherwise negative value return + * @par Example: + * @code + * ... + * int status; + * HapticElement3 elem1; + * elem1.elementtype = HAPTIC_ELEMTYPE_MAGSWEEP; + * elem1.time = 0; + * elem1.TypeSpecific.magsweep.duration = 2900; + * elem1.TypeSpecific.magsweep.magnitude = HAPTIC_MAX_MAGNITUDE; + * elem1.TypeSpecific.magsweep.style = HAPTIC_STYLE_SMOOTH; + * elem1.TypeSpecific.magsweep.attacktime = 2483; + * elem1.TypeSpecific.magsweep.attacklevel = 0; + * elem1.TypeSpecific.magsweep.fadetime = 0; + * elem1.TypeSpecific.magsweep.fadelevel = HAPTIC_MAX_MAGNITUDE; + * + * status = device_haptic_insert_element3(temp_buffer, temp_size, 0, &elem1); + * if (status < 0) { + * return status; + * } + + * ... + * @endcode + */ + + int device_haptic_insert_element3(unsigned char *ivt_buffer, int size, int timeline_index, const HapticElement3 *element); + +/** + * @fn int device_haptic_read_element(const unsigned char *ivt_buffer, int size, int timeline_index, int element_index, HapticElement *element); + * @par Description: + * This API retrieves the parameters of an element of a Timeline effect in an IVT buffer.\n + * @param[in/out] ivt_buffer is a pointer to an IVT buffer + * @param[in] size is a size of the buffer pointed to by ivt_buffer + * @param[in] timeline_index is an index of a Timeline effect in which to read the element + * @param[in] element_index is an index of the element to retrieve + * @param[out] element is a pointer to an HapticElement structure to receive the parameters of a Periodic effect, MagSweepeffect, or Repeat event + * @return if it succeed, it return HAPTIC_S_SUCCESS, otherwise negative value return + * @par Example: + * @code + * ... + * int status; + * HapticElement elem1; + * + * status = device_haptic_insert_element(ivt_buffer, size, 0, 0, &elem1); + * if (status < 0) { + * return status; + * } + + * ... + * @endcode + */ + + + int device_haptic_read_element(const unsigned char *ivt_buffer, int size, int timeline_index, int element_index, HapticElement *element); + +/** + * @fn int device_haptic_read_element2(const unsigned char *ivt_buffer, int size, int timeline_index, int element_index, HapticElement2 *element); + * @par Description: + * This API retrieves the parameters of an element of a Timeline effect in an IVT buffer.\n + * @param[in/out] ivt_buffer is a pointer to an IVT buffer + * @param[in] size is a size of the buffer pointed to by ivt_buffer + * @param[in] timeline_index is an index of a Timeline effect in which to read the element + * @param[in] element_index is an index of the element to retrieve + * @param[out] element is a pointer to an HapticElement2 structure to receive the parameters of a Periodic effect, MagSweepeffect, or Repeat event + * @return if it succeed, it return HAPTIC_S_SUCCESS, otherwise negative value return + * @par Example: + * @code + * ... + * int status; + * HapticElement2 elem1; + * + * status = device_haptic_insert_element2(ivt_buffer, size, 0, 0, &elem1); + * if (status < 0) { + * return status; + * } + + * ... + * @endcode + */ + + int device_haptic_read_element2(const unsigned char *ivt_buffer, int size, int timeline_index, int element_index, HapticElement2 *element); + +/** + * @fn int device_haptic_read_element3(const unsigned char *ivt_buffer, int size, int timeline_index, int element_index, HapticElement3 *element); + * @par Description: + * This API retrieves the parameters of an element of a Timeline effect in an IVT buffer.\n + * @param[in/out] ivt_buffer is a pointer to an IVT buffer + * @param[in] size is a size of the buffer pointed to by ivt_buffer + * @param[in] timeline_index is an index of a Timeline effect in which to read the element + * @param[in] element_index is an index of the element to retrieve + * @param[out] element is a pointer to an HapticElement3 structure to receive the parameters of a Periodic effect, MagSweepeffect, or Repeat event + * @return if it succeed, it return HAPTIC_S_SUCCESS, otherwise negative value return + * @par Example: + * @code + * ... + * int status; + * HapticElement3 elem1; + * + * status = device_haptic_insert_element3(ivt_buffer, size, 0, 0, &elem1); + * if (status < 0) { + * return status; + * } + + * ... + * @endcode + */ + + int device_haptic_read_element3(const unsigned char *ivt_buffer, int size, int timeline_index, int element_index, HapticElement3 *element); + +/** + * @fn int device_haptic_remove_element(unsigned char *ivt_buffer, int size, int timeline_index, int element_index); + * @par Description: + * This API removes the element at the specified index from a Timeline effect in an IVT buffer.\n + * @param[in/out] ivt_buffer is a pointer to an IVT buffer + * @param[in] size is a size of the buffer pointed to by ivt_buffer + * @param[in] timeline_index is an index of a Timeline effect to remove the element from + * @param[in] element_index is an index of the element to remove + * @return if it succeed, it return HAPTIC_S_SUCCESS, otherwise negative value return + * @par Example: + * @code + * ... + * int status; + * HapticElement3 elem1; + * + * status = device_haptic_remove_element(ivt_buffer, size, 0, 0); + * if (status < 0) { + * return status; + * } + + * ... + * @endcode + */ + + int device_haptic_remove_element(unsigned char *ivt_buffer, int size, int timeline_index, int element_index); + + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif +#endif /* __DEVMAN_HAPTIC_EXT_H__ */ diff --git a/devman_haptic_ext_core.h b/devman_haptic_ext_core.h new file mode 100644 index 0000000..6659d54 --- /dev/null +++ b/devman_haptic_ext_core.h @@ -0,0 +1,377 @@ +/* + * devman + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: DongGi Jang + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * +*/ + + +#ifndef __DEVMAN_HAPTIC_EXT_CORE_H__ +#define __DEVMAN_HAPTIC_EXT_CORE_H__ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @file devman_haptic_ext_core.h + * @ingroup DEVICE_MANAGER + * @brief This file contains the data type, structure and definitions of the haptic extra API + * @author SLP2.0 + * @date 2010-01-24 + * @version 0.1 + */ + +/** + * @addtogroup DEVICE_MANAGER + * @{ + */ + +/** + * @par Description: + * Data types level for haptic extra functions. + */ +#define HAPTIC_MAX_MAGNITUDE 10000 /*!< Maximum Force Magnitude */ +#define HAPTIC_MIN_MAGNITUDE 0 /*!< Minimum Force Magnitude */ + +/** + * @par Description: + * Data types level for haptic extra functions. + */ +#define HAPTIC_MAX_EFFECT_NAME_LENGTH 128 /*!< Maximum effect name length */ +#define HAPTIC_INVALID_INDEX -1 /*!< Invalid Index */ + +/* DevicePropertyType */ +#define HAPTIC_DEVPROPTYPE_PRIORITY 1 /*!< Property type constant to set device priority */ +#define HAPTIC_DEVPROPTYPE_DISABLE_EFFECTS 2 /*!< Property type constant to enable/disable effects on a device */ +#define HAPTIC_DEVPROPTYPE_STRENGTH 3 /*!< Property type constant to set the strength (volume) on a device */ +#define HAPTIC_DEVPROPTYPE_MASTERSTRENGTH 4 /*!< Property type constant to set the strength (volume) on ALL devices */ + +/* Device type returned by device_haptic_get_device_capability_int32 in 'xxxx' field of + 'yyyy' struct for 'deviceCapabilityType' equal to + HAPTIC_DEVCAPTYPE_DEVICE_CATEGORY */ +#define HAPTIC_DEVICECATEGORY_IFC 0 /*!< Device category constant for IFC Devices */ +#define HAPTIC_DEVICECATEGORY_IMPULSE 1 /*!< Device category constant for Impulse Devices */ +#define HAPTIC_DEVICECATEGORY_VIRTUAL 2 /*!< Device category constant for Virtual Devices */ +#define HAPTIC_DEVICECATEGORY_EMBEDDED 3 /*!< Device category constant for Embedded Devices */ +#define HAPTIC_DEVICECATEGORY_TETHERED 4 /*!< Device category constant for Tethered Devices */ +#define HAPTIC_DEVICECATEGORY_IMMERSION_USB 5 /*!< Device category constant for Immersion USB Devices */ +#define HAPTIC_DEVICECATEGORY_COMPOSITE 6 /*!< Device category constant for Composite Devices */ + +/* Effect type returned by device_haptic_get_IVT_effect_type */ +#define HAPTIC_EFFECT_TYPE_PERIODIC 0 /*!< Periodic Effect type constant */ +#define HAPTIC_EFFECT_TYPE_MAGSWEEP 1 /*!< Magsweep Effect type constant */ +#define HAPTIC_EFFECT_TYPE_TIMELINE 2 /*!< Timeline Effect type constant */ +#define HAPTIC_EFFECT_TYPE_STREAMING 3 /*!< Streaming Effect type constant */ +#define HAPTIC_EFFECT_TYPE_WAVEFORM 4 /*!< Waveform Effect type constant */ + +/* Device capability type passed as input 'deviceCapabilityType' argument to device_haptic_get_device_capability_... */ +#define HAPTIC_DEVCAPTYPE_DEVICE_CATEGORY 0 /*!< Use device_haptic_get_device_capability_int32 >*/ +#define HAPTIC_DEVCAPTYPE_MAX_NESTED_REPEATS 1 /*!< Use device_haptic_get_device_capability_int32 */ +#define HAPTIC_DEVCAPTYPE_NUM_ACTUATORS 2 /*!< Use device_haptic_get_device_capability_int32 */ +#define HAPTIC_DEVCAPTYPE_ACTUATOR_TYPE 3 /*!< Use device_haptic_get_device_capability_int32 */ +#define HAPTIC_DEVCAPTYPE_NUM_EFFECT_SLOTS 4 /*!< Use device_haptic_get_device_capability_int32 */ +#define HAPTIC_DEVCAPTYPE_SUPPORTED_STYLES 5 /*!< Use device_haptic_get_device_capability_int32 */ +/* HAPTIC_DEVCAPTYPE_SUPPORTED_CONTROL_MODES is deprecated and will not be an available constant +** in future versions of this software. Please use HAPTIC_DEVCAPTYPE_SUPPORTED_STYLES instead. */ +#define HAPTIC_DEVCAPTYPE_SUPPORTED_CONTROL_MODES HAPTIC_DEVCAPTYPE_SUPPORTED_STYLES +#define HAPTIC_DEVCAPTYPE_MIN_PERIOD 6 /*!< Use device_haptic_get_device_capability_int32 */ +#define HAPTIC_DEVCAPTYPE_MAX_PERIOD 7 /*!< Use device_haptic_get_device_capability_int32 */ +#define HAPTIC_DEVCAPTYPE_MAX_EFFECT_DURATION 8 /*!< Use device_haptic_get_device_capability_int32 */ +#define HAPTIC_DEVCAPTYPE_SUPPORTED_EFFECTS 9 /*!< Use device_haptic_get_device_capability_int32 */ +#define HAPTIC_DEVCAPTYPE_DEVICE_NAME 10 /*!< Use device_haptic_get_device_capability_string */ +#define HAPTIC_DEVCAPTYPE_MAX_ENVELOPE_TIME 11 /*!< Use device_haptic_get_device_capability_int32 */ +#define HAPTIC_DEVCAPTYPE_APIVERSIONNUMBER 12 /*!< Use device_haptic_get_device_capability_int32 */ +#define HAPTIC_DEVCAPTYPE_MAX_IVT_SIZE_TETHERED 13 /*!< Use device_haptic_get_device_capability_int32 */ +#define HAPTIC_DEVCAPTYPE_MAX_IVT_SIZE 14 /*!< Use device_haptic_get_device_capability_int32 */ +#define HAPTIC_DEVCAPTYPE_EDITION_LEVEL 15 /*!< Use device_haptic_get_device_capability_int32 */ +#define HAPTIC_DEVCAPTYPE_SUPPORTED_WAVE_TYPES 16 /*!< Use device_haptic_get_device_capability_int32 */ +#define HAPTIC_DEVCAPTYPE_HANDSET_INDEX 17 /*!< Use device_haptic_get_device_capability_int32 */ + +/* Handles */ +#define HAPTIC_INVALID_EFFECT_HANDLE_VALUE -1 /*!< Invalid Effect Handle */ +#define HAPTIC_INVALID_DEVICE_HANDLE_VALUE -1 /*!< Invalid Device Handle */ + +/* Periodic, MagSweep effect Styles are only 4 bits and may be combined with other flags */ +#define HAPTIC_STYLE_MASK 0x0F /*!< Style mask */ + +/* Periodic, MagSweep effect Styles */ +#define HAPTIC_STYLE_SMOOTH 0 /*!< "Smooth" style */ +#define HAPTIC_STYLE_STRONG 1 /*!< "Strong" style */ +#define HAPTIC_STYLE_SHARP 2 /*!< "Sharp" style */ + +#define HAPTIC_DEFAULT_STYLE HAPTIC_STYLE_STRONG + +/* HAPTIC_CONTROLMODE_ constants are deprecated and will not be available +** in future versions of this software. Please use the HAPTIC_STYLE_ constants instead. */ +#define HAPTIC_CONTROLMODE_SMOOTH HAPTIC_STYLE_SMOOTH +#define HAPTIC_CONTROLMODE_STRONG HAPTIC_STYLE_STRONG +#define HAPTIC_CONTROLMODE_SHARP HAPTIC_STYLE_SHARP + +#define HAPTIC_DEFAULT_CONTROLMODE HAPTIC_DEFAULT_STYLE + +/* Effect period resolution */ +#define HAPTIC_PERIOD_RESOLUTION_MICROSECOND 0x80000000 + +/* Periodic effect Wave Types are only 4 bits and may be combined with other flags */ +#define HAPTIC_WAVETYPE_SHIFT 4 /*!< Wave type shift */ +#define HAPTIC_WAVETYPE_MASK 0xF0 /*!< Wave type mask */ + +/* Periodic effect Wave Types */ +#define HAPTIC_WAVETYPE_SQUARE (1 << HAPTIC_WAVETYPE_SHIFT) /*!< "Square" wave type */ +#define HAPTIC_WAVETYPE_TRIANGLE (2 << HAPTIC_WAVETYPE_SHIFT) /*!< "Triangle" wave type */ +#define HAPTIC_WAVETYPE_SINE (3 << HAPTIC_WAVETYPE_SHIFT) /*!< "Sine" wave type */ +#define HAPTIC_WAVETYPE_SAWTOOTHUP (4 << HAPTIC_WAVETYPE_SHIFT) /*!< "Sawtooth Up" wave type */ +#define HAPTIC_WAVETYPE_SAWTOOTHDOWN (5 << HAPTIC_WAVETYPE_SHIFT) /*!< "Sawtooth Down" wave type */ + +#define HAPTIC_DEFAULT_WAVETYPE HAPTIC_WAVETYPE_SQUARE + +/* String length constants */ +#define HAPTIC_MAX_DEVICE_NAME_LENGTH 64 /*!> HAPTIC_WAVETYPE_SHIFT)) /*!< Bitmask for "Square" wave type support */ +#define HAPTIC_WAVETYPE_TRIANGLE_SUPPORT (0x10000 << (HAPTIC_WAVETYPE_TRIANGLE >> HAPTIC_WAVETYPE_SHIFT)) /*!< Bitmask for "Triangle" wave type support */ +#define HAPTIC_WAVETYPE_SINE_SUPPORT (0x10000 << (HAPTIC_WAVETYPE_SINE >> HAPTIC_WAVETYPE_SHIFT)) /*!< Bitmask for "Sine" wave type support */ +#define HAPTIC_WAVETYPE_SAWTOOTHUP_SUPPORT (0x10000 << (HAPTIC_WAVETYPE_SAWTOOTHUP >> HAPTIC_WAVETYPE_SHIFT)) /*!< Bitmask for "Saw tooth up" wave type support */ +#define HAPTIC_WAVETYPE_SAWTOOTHDOWN_SUPPORT (0x10000 << (HAPTIC_WAVETYPE_SAWTOOTHDOWN >> HAPTIC_WAVETYPE_SHIFT)) /*!< Bitmask for "Saw tooth down" wave type support */ + +/* HAPTIC_CONTROLMODE_*_SUPPORT constants are deprecated and will not be available +** in future versions of this software. Please use the HAPTIC_STYLE_*_SUPPORT constants instead. */ +#define HAPTIC_CONTROLMODE_SMOOTH_SUPPORT HAPTIC_STYLE_SMOOTH_SUPPORT +#define HAPTIC_CONTROLMODE_STRONG_SUPPORT HAPTIC_STYLE_STRONG_SUPPORT +#define HAPTIC_CONTROLMODE_SHARP_SUPPORT HAPTIC_STYLE_SHARP_SUPPORT + +/* Device State constants */ +#define HAPTIC_DEVICESTATE_ATTACHED (1 << 0) /*!< Device is attached to the system */ +#define HAPTIC_DEVICESTATE_BUSY (1 << 1) /*!< Device is busy (playing effects) */ + +/* Time in milliseconds */ +#define HAPTIC_TIME_INFINITE HAPTIC_INT32_MAX /*!< Infinite time */ + +/* Effect priority */ +#define HAPTIC_MIN_DEVICE_PRIORITY 0x0 /*!< Minimum Effect priority */ +#define HAPTIC_MAX_DEV_DEVICE_PRIORITY 0x7 /*!< Maximum Effect priority for developers */ +#define HAPTIC_MAX_OEM_DEVICE_PRIORITY 0xF /*!< Maximum Effect priority for OEMs */ +#define HAPTIC_MAX_DEVICE_PRIORITY HAPTIC_MAX_OEM_DEVICE_PRIORITY /*!< FOR BACKWARD COMPATIBILITY ONLY; + new applications should use HAPTIC_MAX_DEV_DEVICE_PRIORITY + or HAPTIC_MAX_OEM_DEVICE_PRIORITY */ + + +/* Device Actuator Type constants */ +#define HAPTIC_DEVACTUATORTYPE_ERM 0 +#define HAPTIC_DEVACTUATORTYPE_BLDC 1 +#define HAPTIC_DEVACTUATORTYPE_LRA 2 +#define HAPTIC_DEVACTUATORTYPE_PIEZO 4 +#define HAPTIC_DEVACTUATORTYPE_PIEZO_WAVE 4 + +/* Device Default priority value */ +#define HAPTIC_DEVPRIORITY_DEFAULT 0 + +/* Repeat count */ +#define HAPTIC_REPEAT_COUNT_INFINITE 255 /*!< Infinite repeat count */ + +/* Streaming Sample */ +#define HAPTIC_MAX_STREAMING_SAMPLE_SIZE 255 /*!< Maximum size for streaming sample */ + +/* Effect state returned by ImmVibeGetEffectState */ +#define HAPTIC_EFFECT_STATE_NOT_PLAYING 0 /*!< Not Playing and not paused */ +#define HAPTIC_EFFECT_STATE_PLAYING 1 /*!< Playing */ +#define HAPTIC_EFFECT_STATE_PAUSED 2 /*!< Paused */ + +/* Edition levels */ +#define HAPTIC_EDITION_3000 3000 +#define HAPTIC_EDITION_4000 4000 +#define HAPTIC_EDITION_5000 5000 + +/* Element type for IVTElement structure that is used by ImmVibeInsertIVTElement, ImmVibeReadIVTElement and ImmVibeRemoveIVTElement */ +#define HAPTIC_ELEMTYPE_PERIODIC 0 +#define HAPTIC_ELEMTYPE_MAGSWEEP 1 +#define HAPTIC_ELEMTYPE_REPEAT 2 +/* New in API v3.4 */ +#define HAPTIC_ELEMTYPE_WAVEFORM 3 + +/* Composite device */ +#define HAPTIC_MAX_LOGICAL_DEVICE_COUNT 16 /*!< Maximum number of device indices that can be passed to ImmVibeOpenCompositeDevice */ + +/**************************************************************************** + * + * General macros + * + ****************************************************************************/ +#define HAPTIC_SUCCEEDED(n) ((n) >= 0) +#define HAPTIC_FAILED(n) ((n) < 0) +#define HAPTIC_IS_INVALID_DEVICE_HANDLE(n) (((n) == 0) || ((n) == HAPTIC_INVALID_DEVICE_HANDLE_VALUE)) +#define HAPTIC_IS_INVALID_EFFECT_HANDLE(n) (((n) == 0) || ((n) == HAPTIC_INVALID_EFFECT_HANDLE_VALUE)) +#define HAPTIC_IS_VALID_DEVICE_HANDLE(n) (((n) != 0) && ((n) != HAPTIC_INVALID_DEVICE_HANDLE_VALUE)) +#define HAPTIC_IS_VALID_EFFECT_HANDLE(n) (((n) != 0) && ((n) != HAPTIC_INVALID_EFFECT_HANDLE_VALUE)) + +/**************************************************************************** + * + * Error and Return value codes. + * + ****************************************************************************/ +#define HAPTIC_S_SUCCESS 0 /*!< Success */ +#define HAPTIC_S_FALSE 0 /*!< False */ +#define HAPTIC_S_TRUE 1 /*!< True */ +#define HAPTIC_W_NOT_PLAYING 1 /*!< Effect is not playing */ +#define HAPTIC_W_INSUFFICIENT_PRIORITY 2 /*!< Effect doesn't have enough priority to play: higher priority effect is playing on the device */ +#define HAPTIC_W_EFFECTS_DISABLED 3 /*!< Effects are disabled on the device */ +#define HAPTIC_W_NOT_PAUSED 4 /*!< The ImmVibeResumePausedEffect function cannot resume an effect that is not paused */ +#define HAPTIC_E_NOT_INITIALIZED -2 /*!< The API is already is not initialized */ +#define HAPTIC_E_INVALID_ARGUMENT -3 /*!< Invalid argument was used in a API function call */ +#define HAPTIC_E_FAIL -4 /*!< Generic error */ +#define HAPTIC_E_INCOMPATIBLE_EFFECT_TYPE -5 /*!< Incompatible Effect type has been passed into API function call */ +#define HAPTIC_E_INCOMPATIBLE_CAPABILITY_TYPE -6 /*!< Incompatible Capability type was used into one of the following functions */ +#define HAPTIC_E_INCOMPATIBLE_PROPERTY_TYPE -7 /*!< Incompatible Property type was used into one of the following functions */ +#define HAPTIC_E_DEVICE_NEEDS_LICENSE -8 /*!< Access to the instance of the device is locked until a valid license key is provided. */ +#define HAPTIC_E_NOT_ENOUGH_MEMORY -9 /*!< The API function cannot allocate memory to complete the process */ +#define HAPTIC_E_SERVICE_NOT_RUNNING -10 /*!< ImmVibeService is not running */ +#define HAPTIC_E_INSUFFICIENT_PRIORITY -11 /*!< Not enough priority to achieve the request (insufficient license key priority) */ +#define HAPTIC_E_SERVICE_BUSY -12 /*!< ImmVibeService is busy and failed to complete the request */ +#define HAPTIC_E_NOT_SUPPORTED -13 /*!< The API function is not supported by this version of the API */ + +/**************************************************************************** + * + * Stuctures + * + ****************************************************************************/ +typedef struct +{ + int duration; + int magnitude; + int period; + int style; + int attacktime; + int attacklevel; + int fadetime; + int fadelevel; +} HapticPeriodic; + +typedef struct +{ + int duration; + int magnitude; + int period; + int style; + int attacktime; + int attacklevel; + int fadetime; + int fadelevel; + int actuatorindex; +} HapticPeriodic2; + +typedef struct +{ + int duration; + int magnitude; + int style; + int attacktime; + int attacklevel; + int fadetime; + int fadelevel; +} HapticMagSweep; + +typedef struct +{ + int duration; + int magnitude; + int style; + int attacktime; + int attacklevel; + int fadetime; + int fadelevel; + int actuatorindex; +} HapticMagSweep2; + +typedef struct +{ + int count; + int duration; +} HapticRepeat; + +typedef struct +{ + const unsigned char *data; + int datasize; + int samplingrate; + int bitdepth; + int magnitude; + int actuatorindex; +} HapticWaveform; + +typedef struct +{ + int elementtype; + int time; + union + { + HapticPeriodic periodic; + HapticMagSweep magsweep; + HapticRepeat repeat; + } TypeSpecific; +} HapticElement; + +typedef struct +{ + int elementtype; + int time; + union + { + HapticPeriodic2 periodic; + HapticMagSweep2 magsweep; + HapticRepeat repeat; + } TypeSpecific; +} HapticElement2; + +typedef struct +{ + int elementtype; + int time; + union + { + HapticPeriodic2 periodic; + HapticMagSweep2 magsweep; + HapticRepeat repeat; + HapticWaveform waveform; + } TypeSpecific; +} HapticElement3; + +#ifdef __cplusplus +} +#endif +#endif /* __DEVMAN_HAPTIC_EXT_CORE_H__ */ diff --git a/devman_internal.c b/devman_internal.c new file mode 100644 index 0000000..94f484b --- /dev/null +++ b/devman_internal.c @@ -0,0 +1,126 @@ +/* + * devman + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: DongGi Jang + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * +*/ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "devlog.h" +#include "devman_internal.h" + +#define WD_RESPONSE_TIMEOUT 100 /* 0.1 seconds */ +#define DISPLAY_WD_PATH "/usr/bin/display_wd" + +static int fifo_fd; + +API int display_register_postjob(void) +{ + int ret, i; + long open_max; + pid_t pid; + char buf[PATH_MAX]; + char fifo_path[NAME_MAX]; + struct pollfd fifo_pollfd; + + snprintf(fifo_path, NAME_MAX, "%s.%d", DISPLAY_WD_FIFO, getpid()); + if (access(fifo_path, F_OK) == 0) { + ERR("Already registered!"); + return -1; + } + mkfifo(fifo_path, 0700); + + pid = fork(); + if(pid < 0) { + ERR("Failed to fork child process for LCD On/Off"); + unlink(fifo_path); + return -1; + } + if (pid == 0) { + open_max = sysconf(_SC_OPEN_MAX); + for (i = 0; i < open_max; i++) { + close(i); + } + + execl(DISPLAY_WD_PATH, DISPLAY_WD_PATH, NULL); + } + + fifo_pollfd.fd = open(fifo_path, O_RDWR | O_NONBLOCK); + if (fifo_pollfd.fd < 0) { + ERR("Cannot open fifo file"); + unlink(fifo_path); + return -1; + } + + /* get the watch dog ready message. */ + fifo_pollfd.events = POLLIN; + if (poll(&fifo_pollfd, 1, WD_RESPONSE_TIMEOUT) < 0) { + ERR("Cannot poll the fifo file"); + DBG("fifo file path is %s", fifo_path); + close(fifo_pollfd.fd); + unlink(fifo_path); + return -1; + } + read(fifo_pollfd.fd, buf, sizeof(buf)); + + fifo_fd = fifo_pollfd.fd; + + return 0; +} + +API int display_cancel_postjob(void) +{ + char buf[PATH_MAX]; + int ret; + + snprintf(buf, PATH_MAX, "%s.%d", DISPLAY_WD_FIFO, getpid()); + if (access(buf, F_OK) != 0) { + ERR("No registered the post job!"); + return -1; + } + + if (fifo_fd < 0) + fifo_fd = open(buf, O_WRONLY); + if (fifo_fd < 0) { + ERR("Cannot open the fifo file"); + DBG("fifo file path is %s", buf); + return -1; + } + ret = DISPLAY_WD_CANCEL; + write(fifo_fd, &ret, sizeof(int)); + close(fifo_fd); + unlink(buf); + fifo_fd = -1; + + return 0; +} + diff --git a/devman_internal.h b/devman_internal.h new file mode 100644 index 0000000..b197bee --- /dev/null +++ b/devman_internal.h @@ -0,0 +1,32 @@ +/* + * devman + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: DongGi Jang + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * +*/ + + +#ifndef API +#define API __attribute__ ((visibility("default"))) +#endif + +#define DISPLAY_WD_FIFO "/tmp/.display_wd" +#define DISPLAY_WD_CANCEL 226235 + +int display_register_postjob(void); +int display_cancel_postjob(void); + diff --git a/display_wd.c b/display_wd.c new file mode 100644 index 0000000..1ba191e --- /dev/null +++ b/display_wd.c @@ -0,0 +1,113 @@ +/* + * devman + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: DongGi Jang + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * +*/ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "device_engine.h" +#include "devman_internal.h" +#include +#include + +char fifo_path[NAME_MAX]; +struct pollfd fifo_pollfd; + +static void sig_quit(int signo) +{ + fprintf(stderr, "[DISPLAY_WD] display_wd will be exit for signal %d\n", signo); + if(fifo_pollfd.fd >= 0) + close(fifo_pollfd.fd); + if (access(fifo_path, F_OK) == 0) + unlink(fifo_path); +} + +int main(void) +{ + int fd, ret, val = -1; + fifo_pollfd.fd = -1; + setsid(); + + signal(SIGPIPE, sig_quit); + + snprintf(fifo_path, NAME_MAX, "%s.%d", DISPLAY_WD_FIFO, getppid()); + fifo_pollfd.fd = open(fifo_path, O_WRONLY); + if (fifo_pollfd.fd < 0) { + fprintf(stderr, "[DISPLAY_WD] Cannot open the fifo file - %s.\n", + fifo_path); + return -1; + } + + /* waitting for parent process ready */ + usleep(10000); + ret = write(fifo_pollfd.fd, "ack", strlen("ack") + 1); + + close(fifo_pollfd.fd); + + fifo_pollfd.fd = open(fifo_path, O_RDONLY); + if (fifo_pollfd.fd < 0) { + fprintf(stderr, "[DISPLAY_WD] Cannot open the fifo file - %s.\n", + fifo_path); + return -1; + } + + fifo_pollfd.events = (POLLIN | POLLHUP); + ret = 0; + while (ret != DISPLAY_WD_CANCEL) { + if (poll(&fifo_pollfd, 1, -1) < 0) { + fprintf(stderr, + "[DISPLAY_WD] Cannot poll the fifo file - %s\n", + fifo_path); + close(fifo_pollfd.fd); + return -1; + } + if (fifo_pollfd.revents & POLLIN) { + read(fifo_pollfd.fd, &ret, sizeof(int)); + if (ret == DISPLAY_WD_CANCEL) { + fprintf(stderr, + "[DISPLAY_WD] Canceled. - %s, %d\n", + fifo_path, ret); + close(fifo_pollfd.fd); + return -1; + } + } + if (fifo_pollfd.revents & POLLHUP) + break; + } + close(fifo_pollfd.fd); + unlink(fifo_path); + + ret = vconf_get_int(VCONFKEY_SETAPPL_LCD_BRIGHTNESS, &val); + + if (ret == 0 && val > 0) { + device_set_property(DEVTYPE_DISPLAY0, DISPLAY_PROP_BRIGHTNESS, val); + device_set_property(DEVTYPE_LED, LED_PROP_BRIGHTNESS, 0); + } + + return 0; +} diff --git a/generic_haptic.c b/generic_haptic.c new file mode 100644 index 0000000..19534fc --- /dev/null +++ b/generic_haptic.c @@ -0,0 +1,71 @@ +/* + * devman + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: DongGi Jang + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * +*/ + + +#include "device_engine.h" +#include "device_path.h" +#include "device_haptic.h" + +#define MAX_BUFF 255 + +int generic_class_haptic_get(char *nodename, int prop, int *val) +{ + char tmp[MAX_BUFF]; + switch (prop) { + case HAPTIC_PROP_LEVEL: + snprintf(tmp, MAX_BUFF, "%s/%s/%s", CLASS_HAPTIC, nodename, + "level"); + return sys_get_int(tmp, val); + case HAPTIC_PROP_LEVEL_MAX: + snprintf(tmp, MAX_BUFF, "%s/%s/%s", CLASS_HAPTIC, nodename, + "level_max"); + return sys_get_int(tmp, val); + case HAPTIC_PROP_VALUE: + snprintf(tmp, MAX_BUFF, "%s/%s/%s", CLASS_HAPTIC, nodename, + "value"); + return sys_get_int(tmp, val); + default: + return -1; + } + return 0; +} + +int generic_class_haptic_set(char *nodename, int prop, int val) +{ + char tmp[MAX_BUFF]; + switch (prop) { + case HAPTIC_PROP_ENABLE: + snprintf(tmp, MAX_BUFF, "%s/%s/%s", CLASS_HAPTIC, nodename, + "enable"); + return sys_set_int(tmp, val); + case HAPTIC_PROP_LEVEL: + snprintf(tmp, MAX_BUFF, "%s/%s/%s", CLASS_HAPTIC, nodename, + "level"); + return sys_set_int(tmp, val); + case HAPTIC_PROP_ONESHOT: + snprintf(tmp, MAX_BUFF, "%s/%s/%s", CLASS_HAPTIC, nodename, + "oneshot"); + return sys_set_int(tmp, val); + default: + return -1; + } + return 0; +} diff --git a/generic_jack.c b/generic_jack.c new file mode 100644 index 0000000..10b9216 --- /dev/null +++ b/generic_jack.c @@ -0,0 +1,69 @@ +/* + * devman + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: DongGi Jang + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * +*/ + + +#include "device_engine.h" +#include "device_path.h" + +#define MAX_BUFF 255 + +int generic_jack_interface_get(char *nodename, int prop, int *val) +{ + char tmp[MAX_BUFF]; + switch (prop) { + case JACK_PROP_USB_ONLINE: + snprintf(tmp, MAX_BUFF, "%s/%s", SYS_DEVICE_JACK, "usb_online"); + break; + case JACK_PROP_TA_ONLINE: + snprintf(tmp, MAX_BUFF, "%s/%s", SYS_DEVICE_JACK, "charger_online"); + break; + case JACK_PROP_HDMI_ONLINE: + snprintf(tmp, MAX_BUFF, "%s/%s", SYS_DEVICE_JACK, "hdmi_online"); + break; + case JACK_PROP_EARJACK_ONLINE: + snprintf(tmp, MAX_BUFF, "%s/%s", SYS_DEVICE_JACK, "earjack_online"); + break; + case JACK_PROP_TVOUT_ONLINE: + snprintf(tmp, MAX_BUFF, "%s/%s", SYS_DEVICE_JACK, "tvout_online"); + break; + case JACK_PROP_CRADLE_ONLINE: + snprintf(tmp, MAX_BUFF, "%s/%s", SYS_DEVICE_JACK, "cradle_online"); + break; + default: + return -1; + } + + return sys_get_int(tmp, val); +} + +int generic_jack_interface_set(char *nodename, int prop, int val) +{ + char tmp[MAX_BUFF]; + switch (prop) { + case JACK_PROP_TVOUT_ONLINE: + snprintf(tmp, MAX_BUFF, "%s/%s", SYS_DEVICE_JACK, "tvout_online"); + break; + default: + return -1; + } + + return sys_set_int(tmp, val); +} diff --git a/generic_led.c b/generic_led.c new file mode 100644 index 0000000..49308ef --- /dev/null +++ b/generic_led.c @@ -0,0 +1,57 @@ +/* + * devman + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: DongGi Jang + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * +*/ + + +#include "device_engine.h" +#include "device_path.h" + +#define MAX_BUFF 255 + +int generic_class_led_get(char *nodename, int prop, int *val) +{ + char tmp[MAX_BUFF]; + switch (prop) { + case LED_PROP_BRIGHTNESS: + snprintf(tmp, MAX_BUFF, "%s/%s/%s", CLASS_LED, nodename, + "brightness"); + + return sys_get_int(tmp, val); + case LED_PROP_MAX_BRIGHTNESS: + snprintf(tmp, MAX_BUFF, "%s/%s/%s", CLASS_LED, nodename, + "max_brightness"); + + return sys_get_int(tmp, val); + } + return -1; +} + +int generic_class_led_set(char *nodename, int prop, int val) +{ + char tmp[MAX_BUFF]; + switch (prop) { + case LED_PROP_BRIGHTNESS: + snprintf(tmp, MAX_BUFF, "%s/%s/%s", CLASS_LED, nodename, + "brightness"); + + return sys_set_int(tmp, val); + } + return -1; +} diff --git a/generic_powersupply.c b/generic_powersupply.c new file mode 100644 index 0000000..1cbe6e0 --- /dev/null +++ b/generic_powersupply.c @@ -0,0 +1,48 @@ +/* + * devman + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: DongGi Jang + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * +*/ + + +#include "device_engine.h" +#include "device_path.h" + +#define MAX_BUFF 255 + +int generic_class_power_supply_get(char *nodename, int prop, int *val) +{ + char tmp[MAX_BUFF]; + switch (prop) { + case POWER_SUPPLY_PROP_CAPACITY: + snprintf(tmp, MAX_BUFF, "%s/%s/%s", CLASS_POWERSUPPLY, nodename, + "capacity"); + return sys_get_int(tmp, val); + case POWER_SUPPLY_PROP_CHARGE_NOW: + snprintf(tmp, MAX_BUFF, "%s/%s/%s", CLASS_POWERSUPPLY, nodename, + "charge_now"); + return sys_get_int(tmp, val); + case POWER_SUPPLY_PROP_CHARGE_FULL: + snprintf(tmp, MAX_BUFF, "%s/%s/%s", CLASS_POWERSUPPLY, nodename, + "charge_full"); + return sys_get_int(tmp, val); + default: + return -1; + } + return 0; +} diff --git a/generic_video.c b/generic_video.c new file mode 100644 index 0000000..0c470b4 --- /dev/null +++ b/generic_video.c @@ -0,0 +1,91 @@ +/* + * devman + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: DongGi Jang + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * +*/ + + +#include "device_engine.h" +#include "device_path.h" + +#define MAX_BUFF 255 + +int generic_class_lcd_get(char *nodename, int prop, int *val) +{ + char tmp[MAX_BUFF]; + switch (prop) { + case DISPLAY_PROP_ONOFF: + snprintf(tmp, MAX_BUFF, "%s/%s/%s", CLASS_LCD, nodename, + "lcd_power"); + return sys_get_int(tmp, val); + case DISPLAY_PROP_GAMMA: + snprintf(tmp, MAX_BUFF, "%s/%s/gamma", CLASS_LCD, nodename); + return sys_get_int(tmp, val); + default: + return -1; + } + return 0; +} + +int generic_class_lcd_set(char *nodename, int prop, int val) +{ + char tmp[MAX_BUFF]; + switch (prop) { + case DISPLAY_PROP_ONOFF: + snprintf(tmp, MAX_BUFF, "%s/%s/%s", CLASS_LCD, nodename, + "lcd_power"); + return sys_set_int(tmp, val); + case DISPLAY_PROP_GAMMA: + snprintf(tmp, MAX_BUFF, "%s/%s/gamma", CLASS_LCD, nodename); + return sys_set_int(tmp, val); + default: + return -1; + } + return 0; +} + +int generic_class_backlight_get(char *nodename, int prop, int *val) +{ + char tmp[MAX_BUFF]; + switch (prop) { + case DISPLAY_PROP_BRIGHTNESS: + snprintf(tmp, MAX_BUFF, "%s/%s/%s", CLASS_BACKLIGHT, nodename, + "brightness"); + + return sys_get_int(tmp, val); + case DISPLAY_PROP_MAX_BRIGHTNESS: + snprintf(tmp, MAX_BUFF, "%s/%s/%s", CLASS_BACKLIGHT, nodename, + "max_brightness"); + + return sys_get_int(tmp, val); + } + return -1; +} + +int generic_class_backlight_set(char *nodename, int prop, int val) +{ + char tmp[MAX_BUFF]; + switch (prop) { + case DISPLAY_PROP_BRIGHTNESS: + snprintf(tmp, MAX_BUFF, "%s/%s/%s", CLASS_BACKLIGHT, nodename, + "brightness"); + + return sys_set_int(tmp, val); + } + return -1; +} diff --git a/if_generic.c b/if_generic.c new file mode 100644 index 0000000..82f6106 --- /dev/null +++ b/if_generic.c @@ -0,0 +1,89 @@ +/* + * devman + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: DongGi Jang + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * +*/ + + +#include +#include +#include "devlog.h" +#include "device_engine.h" + +API int device_get_property(devtype_t devtype, int property, int *value) +{ + struct device *dev = NULL; + retry: + if (dev != NULL) { + dev = dev->next; + if (dev == NULL) { + errno = ENODEV; + return -1; + } + } + + dev = find_device(dev, devtype); + if (dev == NULL) { + DBG("devtype cannot find"); + errno = ENODEV; + return -1; + } + if (dev->get_int == NULL) { + DBG("get_int of %s is null", dev->devname); + goto retry; + } + + if (dev->get_int(property, value) == -1) { + DBG("get_int of %s return fails", dev->devname); + goto retry; + } + + errno = 0; + return 0; +} + +API int device_set_property(devtype_t devtype, int property, int value) +{ + struct device *dev = NULL; + retry: + if (dev != NULL) { + dev = dev->next; + if (dev == NULL) { + return -1; + } + } + + dev = find_device(dev, devtype); + if (dev == NULL) { + DBG("devtype cannot find"); + errno = ENODEV; + return -1; + } + if (dev->set_int == NULL) { + errno = EPERM; + goto retry; + } + + if (dev->set_int(property, value) == -1) { + errno = EACCES; + goto retry; + } + + errno = 0; + return 0; +} diff --git a/if_legacy.c b/if_legacy.c new file mode 100644 index 0000000..06d8559 --- /dev/null +++ b/if_legacy.c @@ -0,0 +1,296 @@ +/* + * devman + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: DongGi Jang + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * +*/ + + +#include + +#include "devman_internal.h" +#include "device_engine.h" +#include "device_path.h" +#include "devlog.h" + +#define SET_FLAG(var, bit) (var |= (1< 100) { + ERR("capacity value is wrong"); + return -1; + } + + return val; +} + +API int device_is_battery_full(void) +{ + int capacity = 0, charge_state = 0; + if(device_get_property(DEVTYPE_POWERSUPPLY, POWER_SUPPLY_PROP_CAPACITY, &capacity) < 0) + return -1; + + /* If the capacity is 100 and charge state is 1, battery is not full */ + device_get_property(DEVTYPE_POWERSUPPLY, POWER_SUPPLY_PROP_CHARGE_NOW, &charge_state); + if(capacity < 0 || capacity > 100) { + ERR("capacity value is wrong"); + return -1; + } else if(capacity == 100 && charge_state < 1) { + return 1; + } else { + return 0; + } +} + +API int device_get_display_brt(display_num_t lcdnum) +{ + int val; + + switch (lcdnum) { + case 0: + /* Fall through */ + case 1: + /* check lcd power on/off */ + if (device_get_property + ((DEVTYPE_DISPLAY0 + lcdnum), DISPLAY_PROP_ONOFF, &val) < 0) + return -1; + if (val == 0) + /* lcd is off */ + return 0; + if (device_get_property + ((DEVTYPE_DISPLAY0 + lcdnum), DISPLAY_PROP_BRIGHTNESS, + &val) < 0) + return -1; + break; + default: + return -1; + } + + return val; +} + +API int device_set_display_brt(display_num_t lcdnum, int val) +{ + int bat_state = -1, ret = -1; + switch (lcdnum) { + case 0: + /* Fall through */ + case 1: + if(vconf_get_int(VCONFKEY_SYSMAN_BATTERY_STATUS_LOW, &bat_state) != 0 || bat_state >= VCONFKEY_SYSMAN_BAT_WARNING_LOW ) { + if (device_set_property + ((DEVTYPE_DISPLAY0 + lcdnum), DISPLAY_PROP_BRIGHTNESS, + val) < 0) + return -1; + break; + } else { + ERR("can not set brightness for low battery"); + return -1; + } + default: + return -1; + } + + if (!disp_flag) + ret = display_register_postjob(); + if (ret == 0) + SET_FLAG(disp_flag, BRT_BIT); + return 0; +} + +API int device_release_brt_ctrl(display_num_t lcdnum) +{ + int setting_val=0; + int bat_state=-1; + + switch (lcdnum) { + case 0: + case 1: + if(vconf_get_int(VCONFKEY_SYSMAN_BATTERY_STATUS_LOW, &bat_state) != 0 || bat_state >= VCONFKEY_SYSMAN_BAT_WARNING_LOW ) { + if(vconf_get_int(VCONFKEY_SETAPPL_LCD_BRIGHTNESS, &setting_val) != 0){ + if (device_get_property + ((DEVTYPE_DISPLAY0 + lcdnum), DISPLAY_PROP_MAX_BRIGHTNESS, + &setting_val) < 0) + return -1; + setting_val=setting_val*0.7; + } + + if (device_set_property + ((DEVTYPE_DISPLAY0 + lcdnum), DISPLAY_PROP_BRIGHTNESS, + setting_val) < 0) + return -1; + break; + } else { + ERR("can not set brightness for low battery"); + return -1; + } + default: + return -1; + } + UNSET_FLAG(disp_flag, BRT_BIT); + if (!disp_flag) + display_cancel_postjob(); + return 0; +} + +API int device_get_max_brt(display_num_t lcdnum) +{ + int val = -1; + + switch (lcdnum) { + case 0: + /* Fall through */ + case 1: + /* check lcd power on/off */ + if (device_get_property + ((DEVTYPE_DISPLAY0 + lcdnum), DISPLAY_PROP_MAX_BRIGHTNESS, + &val) < 0) + return -1; + break; + default: + return -1; + } + + return val; +} + +API int device_get_display_gamma(display_num_t lcdnum) +{ + int val = -1; + + switch (lcdnum) { + case 0: + /* Fall through */ + case 1: + /* check lcd power on/off */ + if (device_get_property + ((DEVTYPE_DISPLAY0 + lcdnum), DISPLAY_PROP_GAMMA, &val) < 0) + return -1; + break; + default: + return -1; + } + + return val; +} + +API int device_set_display_gamma(display_num_t lcdnum, display_gamma_t val) +{ + int ret = -1; + switch (lcdnum) { + case 0: + /* Fall through */ + case 1: + if (device_set_property + ((DEVTYPE_DISPLAY0 + lcdnum), DISPLAY_PROP_GAMMA, val) < 0) + return -1; + break; + default: + return -1; + } + + if (!disp_flag) + ret = display_register_postjob(); + if (ret == 0) + SET_FLAG(disp_flag, GAMMA_BIT); + return 0; +} + +API int device_release_gamma_ctrl(display_num_t lcdnum, display_gamma_t org_val) +{ + switch (lcdnum) { + case 0: + /* Fall through */ + case 1: + if (device_set_property + ((DEVTYPE_DISPLAY0 + lcdnum), DISPLAY_PROP_GAMMA, + org_val) < 0) + return -1; + break; + default: + return -1; + } + UNSET_FLAG(disp_flag, GAMMA_BIT); + if (!disp_flag) + display_cancel_postjob(); + return 0; +} + +API int device_get_display_count(void) +{ + int val = -1; + + if (device_get_property + (DEVTYPE_DISPLAY0, DISPLAY_PROP_DISPLAY_COUNT, &val) < 0) + return -1; + + return val; +} + +API int device_power_suspend(void) +{ + return sys_set_str("/sys/power/state", "mem"); +} + +API int device_get_led_brt(void) +{ + int val; + + if (device_get_property(DEVTYPE_LED, LED_PROP_BRIGHTNESS, &val) < 0) + return -1; + + return val; +} + +API int device_set_led_brt(int val) +{ + int ret=-1; + if (device_set_property(DEVTYPE_LED, LED_PROP_BRIGHTNESS, val) < 0) + return -1; + + if (val == 0) { + UNSET_FLAG(disp_flag, LED_BIT); + if (!disp_flag) + display_cancel_postjob(); + } else { + if (!disp_flag) + ret = display_register_postjob(); + if (ret == 0) + SET_FLAG(disp_flag, LED_BIT); + } + return 0; +} + +API int device_get_max_led(void) +{ + int val = -1; + + if (device_get_property(DEVTYPE_LED, LED_PROP_MAX_BRIGHTNESS, &val) < 0) + return -1; + + return val; +} + diff --git a/image/SLP_devman_PG_architecture.png b/image/SLP_devman_PG_architecture.png new file mode 100755 index 0000000000000000000000000000000000000000..1ff6c039fff495dc3962fe716da6bbcbd29a87b3 GIT binary patch literal 59818 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 literal 0 HcmV?d00001 diff --git a/packaging/devman.spec b/packaging/devman.spec new file mode 100644 index 0000000..32fb34c --- /dev/null +++ b/packaging/devman.spec @@ -0,0 +1,86 @@ +#sbs-git:slp/pkgs/d/devman devman_0.1.6-66 62dc621fa0c0ae0ec4855a0e8381978a072304af +Name: devman +Summary: Device manager library +Version: 0.1.6 +Release: 1 +Group: TO_BE/FILLED_IN +License: LGPL 2.1 +Source0: %{name}-%{version}.tar.gz +Requires(post): /sbin/ldconfig +Requires(postun): /sbin/ldconfig +BuildRequires: cmake +BuildRequires: vconf-keys-devel +BuildRequires: sysman-devel +BuildRequires: pkgconfig(vconf) +BuildRequires: pkgconfig(sysman) +BuildRequires: pkgconfig(dlog) +BuildRequires: pkgconfig(heynoti) + +%description +Device manager library for device control + +%package devel +Summary: Device manager library for (devel) +Group: Development/Libraries +Requires: %{name} = %{version}-%{release} + +%description devel +Device manager library for device control (devel) + +%package haptic-devel +Summary: Haptic Device manager library for (devel) +Group: Development/Libraries +Requires: %{name} = %{version}-%{release} +Requires: %{name}-devel = %{version}-%{release} + +%description haptic-devel +Haptic Device manager library for device control (devel) + +%prep +%setup -q + +%build +CFLAGS="$CFLAGS -DS5PC110_2_6_29" cmake . -DCMAKE_INSTALL_PREFIX=%{_prefix} -DCMAKE_DEVMAN_RSRC_PREFIX=share/devman -DCMAKE_MACHINE=aquila -DCMAKE_DATADIR=/opt + +make %{?jobs:-j%jobs} + +%install +rm -rf %{buildroot} +%make_install + +mkdir -p %{buildroot}%{_sysconfdir}/rc.d/rc3.d +mkdir -p %{buildroot}%{_sysconfdir}/rc.d/rc4.d +ln -s %{_sysconfdir}/init.d/devman %{buildroot}%{_sysconfdir}/rc.d/rc3.d/S10devman +ln -s %{_sysconfdir}/init.d/devman %{buildroot}%{_sysconfdir}/rc.d/rc4.d/S10devman + +%post +/sbin/ldconfig +mkdir -p /etc/udev/rules.d +if ! [ -L /etc/udev/rules.d/91-devman.rules ]; then +ln -s /usr/share/devman/udev-rules/91-devman.rules /etc/udev/rules.d/91-devman.rules +fi + +%postun +/sbin/ldconfig +rm -f /etc/udev/rules.d/91-X1.rules + +%files +/etc/rc.d/init.d/devman +%{_bindir}/delete.sm +%{_sbindir}/pdp*.sh +%{_libdir}/libdevman.so.* +%{_datadir}/devman/udev-rules/91-devman.rules +%{_sysconfdir}/rc.d/rc3.d/S10devman +%{_sysconfdir}/rc.d/rc4.d/S10devman + +%files devel +%{_includedir}/devman/devman.h +%{_includedir}/devman/SLP_devman_PG.h +%{_libdir}/pkgconfig/devman.pc +%{_libdir}/libdevman.so + +%files haptic-devel +%{_includedir}/devman/devman_haptic.h +%{_includedir}/devman/devman_haptic_ext.h +%{_includedir}/devman/devman_haptic_ext_core.h +%{_libdir}/pkgconfig/devman_haptic.pc diff --git a/packaging/devman.yaml b/packaging/devman.yaml new file mode 100644 index 0000000..6823284 --- /dev/null +++ b/packaging/devman.yaml @@ -0,0 +1,48 @@ +Name : devman +Version : 0.1.6 +Release : 1 +Group : TO_BE/FILLED_IN +Summary : Device manager library +Description: | + Device manager library for device control +Sources : + - devman-%{version}.tar.gz +Patches : + - devman-0.1.6-open-fix.patch + +PkgBR: + - cmake + - vconf-keys-devel + - sysman-devel + - pkgconfig(vconf) + - pkgconfig(sysman) + - pkgconfig(dlog) + +Configure : none +License: TO BE FILLED IN +Files: + - "%doc COPYING" + - /etc/rc.d/init.d/devman + - "%{_libdir}/libdevman.so.*" + - "%{_datadir}/devman/udev-rules/91-devman.rules" + +SubPackages : + - Name: devel + Summary: Device manager library for (devel) + Description: Device manager library for device control (devel) + Group: Development/Libraries + Files: + - "%{_includedir}/devman/devman.h" + - "%{_includedir}/devman/SLP_devman_PG.h" + - "%{_libdir}/pkgconfig/devman.pc" + - "%{_libdir}/libdevman.so" + + - Name: haptic-devel + Summary: Haptic Device manager library for (devel) + Description: Haptic Device manager library for device control (devel) + Group: Development/Libraries + Files: + - "%{_includedir}/devman/devman_haptic.h" + - "%{_includedir}/devman/devman_haptic_ext.h" + - "%{_includedir}/devman/devman_haptic_ext_core.h" + - "%{_libdir}/pkgconfig/devman_haptic.pc" diff --git a/udev-files/91-devman.rules.in b/udev-files/91-devman.rules.in new file mode 100755 index 0000000..c7afed5 --- /dev/null +++ b/udev-files/91-devman.rules.in @@ -0,0 +1,3 @@ +#pdp0 +ACTION=="add", KERNEL=="pdp0", RUN+="@PREFIX@/sbin/pdp0_up.sh" +ACTION=="remove", KERNEL=="pdp0", RUN+="@PREFIX@/sbin/pdp0_down.sh" -- 2.7.4